Recognizes if input is ogg or not.
[xiph.git] / postfish / mixpanel.c
blob6e69906055194c6aaa6aa7abd2d0bf1ab7665354
1 /*
3 * postfish
4 *
5 * Copyright (C) 2002-2005 Monty
7 * Postfish is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * Postfish is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "postfish.h"
25 #include <gtk/gtk.h>
26 #include <gdk/gdkkeysyms.h>
27 #include "readout.h"
28 #include "multibar.h"
29 #include "mainpanel.h"
30 #include "subpanel.h"
31 #include "feedback.h"
32 #include "mix.h"
33 #include "config.h"
35 typedef struct {
36 GtkWidget *s;
37 GtkWidget *r;
38 sig_atomic_t *val;
39 } slider_readout_pair;
41 /* only the sliders we need to save for feedback */
42 typedef struct {
43 subpanel_generic *panel;
44 slider_readout_pair **att;
45 slider_readout_pair **del;
47 GtkWidget **master;
49 GtkWidget *average;
50 } atten_panelsave;
52 typedef struct {
53 GtkWidget *insert_source[MIX_BLOCKS][3];
54 GtkWidget *insert_invert[MIX_BLOCKS];
55 slider_readout_pair *insert_att[MIX_BLOCKS];
56 slider_readout_pair *insert_del[MIX_BLOCKS];
57 GtkWidget *insert_dest[MIX_BLOCKS][OUTPUT_CHANNELS];
59 GtkWidget *destA[OUTPUT_CHANNELS];
60 GtkWidget *destB[OUTPUT_CHANNELS];
61 slider_readout_pair *place_AB;
62 slider_readout_pair *place_atten;
63 slider_readout_pair *place_delay;
65 GtkWidget *place[2];
66 GtkWidget *sub[MIX_BLOCKS];
67 } mix_panelsave;
69 static atten_panelsave atten_panel;
70 static mix_panelsave **mix_panels;
72 static void mixblock_state_to_config(int bank, mix_settings *s,int A,int B){
73 config_set_vector("mixblock_source",bank,A,B,0,3,s->insert_source[B]);
74 config_set_integer("mixblock_set",bank,A,B,0,0,s->insert_invert[B]);
75 config_set_integer("mixblock_set",bank,A,B,0,1,s->insert_att[B]);
76 config_set_integer("mixblock_set",bank,A,B,0,2,s->insert_delay[B]);
77 config_set_vector("mixblock_dest",bank,A,B,0,OUTPUT_CHANNELS,s->insert_dest[B]);
80 static void mixdown_state_to_config(int bank, mix_settings *s,int A){
81 int i;
82 config_set_vector("mixplace_dest",bank,A,0,0,OUTPUT_CHANNELS,s->placer_destA);
83 config_set_vector("mixplace_dest",bank,A,1,0,OUTPUT_CHANNELS,s->placer_destB);
84 config_set_integer("mixplace_set",bank,A,0,0,0,s->placer_place);
85 config_set_integer("mixplace_set",bank,A,0,0,1,s->placer_att);
86 config_set_integer("mixplace_set",bank,A,0,0,2,s->placer_delay);
87 for(i=0;i<MIX_BLOCKS;i++)
88 mixblock_state_to_config(bank,s,A,i);
91 void mixpanel_state_to_config(int bank){
92 int i;
93 config_set_vector("mixdown_active",bank,0,0,0,input_ch,mixpanel_active);
95 for(i=0;i<input_ch;i++){
96 config_set_integer("mixdown_master_attenuate",bank,0,0,0,i,mix_set[i].master_att);
97 config_set_integer("mixdown_master_delay",bank,0,0,0,i,mix_set[i].master_delay);
99 mixdown_state_to_config(bank,mix_set+i,i);
103 static void mixblock_state_from_config(int bank, mix_settings *s,mix_panelsave *p,int A,int B){
104 int i;
105 config_get_vector("mixblock_source",bank,A,B,0,3,s->insert_source[B]);
106 for(i=0;i<3;i++)
107 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->insert_source[B][i]),
108 s->insert_source[B][i]);
110 config_get_sigat("mixblock_set",bank,A,B,0,0,&s->insert_invert[B]);
111 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->insert_invert[B]),
112 s->insert_invert[B]);
114 config_get_sigat("mixblock_set",bank,A,B,0,1,&s->insert_att[B]);
115 multibar_thumb_set(MULTIBAR(p->insert_att[B]->s),s->insert_att[B]*.1,0);
117 config_get_sigat("mixblock_set",bank,A,B,0,2,&s->insert_delay[B]);
118 multibar_thumb_set(MULTIBAR(p->insert_del[B]->s),s->insert_delay[B]*.01,0);
120 config_get_vector("mixblock_dest",bank,A,B,0,OUTPUT_CHANNELS,s->insert_dest[B]);
121 for(i=0;i<OUTPUT_CHANNELS;i++)
122 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->insert_dest[B][i]),
123 s->insert_dest[B][i]);
126 static void mixdown_state_from_config(int bank, mix_settings *s, mix_panelsave *p, int A){
127 int i;
128 config_get_vector("mixplace_dest",bank,A,0,0,OUTPUT_CHANNELS,s->placer_destA);
129 config_get_vector("mixplace_dest",bank,A,1,0,OUTPUT_CHANNELS,s->placer_destB);
130 config_get_sigat("mixplace_set",bank,A,0,0,0,&s->placer_place);
131 config_get_sigat("mixplace_set",bank,A,0,0,1,&s->placer_att);
132 config_get_sigat("mixplace_set",bank,A,0,0,2,&s->placer_delay);
134 for(i=0;i<OUTPUT_CHANNELS;i++){
135 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->destA[i]),s->placer_destA[i]);
136 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->destB[i]),s->placer_destB[i]);
138 multibar_thumb_set(MULTIBAR(p->place_AB->s),s->placer_place,0);
139 multibar_thumb_set(MULTIBAR(p->place_atten->s),s->placer_att*.1,0);
140 multibar_thumb_set(MULTIBAR(p->place_delay->s),s->placer_delay*.01,0);
142 for(i=0;i<MIX_BLOCKS;i++)
143 mixblock_state_from_config(bank,s,p,A,i);
146 void mixpanel_state_from_config(int bank){
147 int i;
148 config_get_vector("mixdown_active",bank,0,0,0,input_ch,mixpanel_active);
150 for(i=0;i<input_ch;i++){
151 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(atten_panel.panel->subpanel_activebutton[i]),
152 mixpanel_active[i]);
154 config_get_sigat("mixdown_master_attenuate",bank,0,0,0,i,&mix_set[i].master_att);
155 config_get_sigat("mixdown_master_delay",bank,0,0,0,i,&mix_set[i].master_delay);
157 multibar_thumb_set(MULTIBAR(atten_panel.att[i]->s),mix_set[i].master_att*.1,0);
158 multibar_thumb_set(MULTIBAR(atten_panel.del[i]->s),mix_set[i].master_delay*.01,0);
160 mixdown_state_from_config(bank,mix_set+i,mix_panels[i],i);
165 static int av_callback_enter=1;
167 static float determine_average(void){
168 int i;
169 float acc=0;
170 for(i=0;i<input_ch;i++)
171 acc+=multibar_get_value(MULTIBAR(atten_panel.att[i]->s),0);
172 return acc/input_ch;
175 static void av_slider_change(GtkWidget *w,gpointer in){
176 if(!av_callback_enter){
177 atten_panelsave *p=(atten_panelsave *)in;
179 float av=multibar_get_value(MULTIBAR(p->average),0);
180 float actual=determine_average();
181 int i;
183 av_callback_enter=1;
184 for(i=0;i<input_ch;i++){
185 float val=multibar_get_value(MULTIBAR(atten_panel.att[i]->s),0) + av - actual;
186 multibar_thumb_set(MULTIBAR(atten_panel.att[i]->s),val,0);
189 av_callback_enter=0;
193 static void dB_slider_change(GtkWidget *w,gpointer in){
194 char buffer[80];
195 slider_readout_pair *p=(slider_readout_pair *)in;
196 float val=multibar_get_value(MULTIBAR(p->s),0);
198 sprintf(buffer,"%+4.1fdB",val);
199 readout_set(READOUT(p->r),buffer);
201 *p->val=rint(val*10);
203 if(!av_callback_enter){
204 av_callback_enter=1;
205 float actual=determine_average();
206 multibar_thumb_set(MULTIBAR(atten_panel.average),actual,0);
207 av_callback_enter=0;
211 static void ms_slider_change(GtkWidget *w,gpointer in){
212 char buffer[80];
213 slider_readout_pair *p=(slider_readout_pair *)in;
214 float val=multibar_get_value(MULTIBAR(p->s),0);
216 if(val>-1. && val<1.){
217 sprintf(buffer,"%+4.2fms",val);
218 }else{
219 sprintf(buffer,"%+4.1fms",val);
221 readout_set(READOUT(p->r),buffer);
222 *p->val=rint(val*100);
225 static void AB_slider_change(GtkWidget *w,gpointer in){
226 char buffer[80];
227 slider_readout_pair *p=(slider_readout_pair *)in;
228 float val=multibar_get_value(MULTIBAR(p->s),0);
230 if(val==100){
231 sprintf(buffer,"center");
232 }else if(val<100){
233 sprintf(buffer,"A+%d%%",(int)(100-val));
234 }else{
235 sprintf(buffer,"B+%d%%",(int)(val-100));
237 readout_set(READOUT(p->r),buffer);
239 *p->val=rint(val);
242 static void toggle_callback(GtkWidget *w,gpointer in){
243 GtkToggleButton *b=GTK_TOGGLE_BUTTON(w);
244 sig_atomic_t *val=(sig_atomic_t *)in;
246 *val=gtk_toggle_button_get_active(b);
249 static char *labels_dB[11]={""," -60","-40","-20","-10","0","10","20","40","60","80"};
250 static float levels_dB[11]={-80,-60,-40,-20,-10,0,10,20,40,60,80};
252 static char *labels_dBn[6]={"","-40","-20","-10","0","+10"};
253 static float levels_dBn[6]={-80,-40,-20,-10,0,10};
255 static char *labels_del[6]={"","-20","-10","-5","-1","-0"};
256 static float levels_del[6]={-50,-20,-10,-5,-1,0};
259 static mix_panelsave *mixpanel_create_helper(postfish_mainpanel *mp,
260 subpanel_generic *panel,
261 mix_settings *m,
262 int thisch){
264 int i,j;
266 char *labels_dBnn[6]={"","-40","-20","-10","-3","0"};
267 float levels_dBnn[6]={-80,-40,-20,-10,-3,0};
269 char *labels_AB[3]={"A","center","B"};
270 float levels_AB[3]={0,100,200};
272 GtkWidget *table=gtk_table_new(12+MIX_BLOCKS*3,6,0);
273 mix_panelsave *ps=calloc(1,sizeof(*ps));
275 /* crossplace marker */
277 GtkWidget *box=gtk_hbox_new(0,0);
278 GtkWidget *l=gtk_label_new("Crossplace ");
279 GtkWidget *h=gtk_hseparator_new();
281 gtk_widget_set_name(l,"framelabel");
283 gtk_box_pack_start(GTK_BOX(box),l,0,0,0);
284 gtk_box_pack_start(GTK_BOX(box),h,1,1,0);
285 gtk_table_attach(GTK_TABLE(table),box,0,6,2,3,
286 GTK_FILL,0,0,2);
287 gtk_table_set_row_spacing(GTK_TABLE(table),1,10);
290 /* crossplace controls */
292 slider_readout_pair *AB=calloc(1,sizeof(*AB));
293 slider_readout_pair *att=calloc(1,sizeof(*att));
294 slider_readout_pair *del=calloc(1,sizeof(*del));
295 GtkWidget *boxA=gtk_hbox_new(1,0);
296 GtkWidget *boxB=gtk_hbox_new(1,0);
298 GtkWidget *lA=gtk_label_new("output A");
299 GtkWidget *lB=gtk_label_new("output B");
301 GtkWidget *latt=gtk_label_new("crossatten ");
302 GtkWidget *ldel=gtk_label_new("crossdelay ");
303 gtk_misc_set_alignment(GTK_MISC(latt),1,.5);
304 gtk_misc_set_alignment(GTK_MISC(ldel),1,.5);
306 AB->s=multibar_slider_new(3,labels_AB,levels_AB,1);
307 att->s=multibar_slider_new(6,labels_dBnn,levels_dBnn,1);
308 del->s=multibar_slider_new(6,labels_del,levels_del,1);
309 AB->r=readout_new("A+000");
310 att->r=readout_new("+00.0dB");
311 del->r=readout_new("+00.0ms");
312 AB->val=&m->placer_place;
313 att->val=&m->placer_att;
314 del->val=&m->placer_delay;
316 ps->place_AB=AB;
317 ps->place_atten=att;
318 ps->place_delay=del;
320 multibar_callback(MULTIBAR(AB->s),AB_slider_change,AB);
321 multibar_thumb_set(MULTIBAR(AB->s),100,0);
322 multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
323 multibar_thumb_set(MULTIBAR(att->s),-3,0);
324 multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
325 multibar_thumb_set(MULTIBAR(del->s),-1,0);
327 ps->place[0]=multibar_new(6,labels_dBn,levels_dBn,0,
328 LO_ATTACK|LO_DECAY|HI_DECAY);
329 ps->place[1]=multibar_new(6,labels_dBn,levels_dBn,0,
330 LO_ATTACK|LO_DECAY|HI_DECAY);
332 for(i=0;i<OUTPUT_CHANNELS;i++){
333 char buffer[80];
334 GtkWidget *bA,*bB;
336 sprintf(buffer," %d ",i+1);
338 bA=gtk_toggle_button_new_with_label(buffer);
339 bB=gtk_toggle_button_new_with_label(buffer);
341 gtk_box_pack_start(GTK_BOX(boxA),bA,1,1,0);
342 gtk_box_pack_start(GTK_BOX(boxB),bB,1,1,0);
344 g_signal_connect (G_OBJECT (bA), "clicked",
345 G_CALLBACK (toggle_callback),
346 (gpointer)&m->placer_destA[i]);
347 g_signal_connect (G_OBJECT (bB), "clicked",
348 G_CALLBACK (toggle_callback),
349 (gpointer)&m->placer_destB[i]);
351 ps->destA[i]=bA;
352 ps->destB[i]=bB;
355 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ps->destA[0]),1);
356 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ps->destB[1]),1);
358 gtk_table_attach(GTK_TABLE(table),lA,0,2,6,7,
359 0,0,0,0);
360 gtk_table_attach(GTK_TABLE(table),lB,5,6,6,7,
361 0,0,0,0);
363 gtk_table_attach(GTK_TABLE(table),ps->place[0],0,2,4,5,
364 GTK_FILL|GTK_EXPAND,0,0,0);
365 gtk_table_attach(GTK_TABLE(table),ps->place[1],5,6,4,5,
366 GTK_FILL|GTK_EXPAND,0,0,0);
368 gtk_table_attach(GTK_TABLE(table),boxA,0,2,5,6,
369 GTK_FILL|GTK_EXPAND,0,0,0);
370 gtk_table_attach(GTK_TABLE(table),boxB,5,6,5,6,
371 GTK_FILL|GTK_EXPAND,0,0,0);
372 gtk_table_attach(GTK_TABLE(table),AB->s,2,4,4,5,
373 GTK_FILL|GTK_EXPAND,0,2,0);
374 gtk_table_attach(GTK_TABLE(table),att->s,3,4,5,6,
375 GTK_FILL|GTK_EXPAND,0,2,0);
376 gtk_table_attach(GTK_TABLE(table),del->s,3,4,6,7,
377 GTK_FILL|GTK_EXPAND,0,2,0);
378 gtk_table_attach(GTK_TABLE(table),AB->r,4,5,4,5,
379 GTK_FILL|GTK_EXPAND,0,0,0);
380 gtk_table_attach(GTK_TABLE(table),att->r,4,5,5,6,
381 GTK_FILL|GTK_EXPAND,0,0,0);
382 gtk_table_attach(GTK_TABLE(table),del->r,4,5,6,7,
383 GTK_FILL|GTK_EXPAND,0,0,0);
385 gtk_table_attach(GTK_TABLE(table),latt,2,3,5,6,
386 GTK_FILL,0,0,0);
387 gtk_table_attach(GTK_TABLE(table),ldel,2,3,6,7,
388 GTK_FILL,0,0,0);
393 /* Direct Mix marker */
395 GtkWidget *box=gtk_hbox_new(0,0);
396 GtkWidget *l=gtk_label_new("Direct Mixdown Blocks ");
397 GtkWidget *h=gtk_hseparator_new();
399 GtkWidget *ls=gtk_label_new("source");
400 GtkWidget *lo=gtk_label_new("output");
402 gtk_widget_set_name(l,"framelabel");
404 gtk_box_pack_start(GTK_BOX(box),l,0,0,0);
405 gtk_box_pack_start(GTK_BOX(box),h,1,1,0);
407 gtk_table_attach(GTK_TABLE(table),box,0,6,7,8,
408 GTK_FILL,0,0,2);
409 gtk_table_attach(GTK_TABLE(table),ls,0,2,11+MIX_BLOCKS*3,12+MIX_BLOCKS*3,
410 GTK_FILL,0,0,2);
411 gtk_table_attach(GTK_TABLE(table),lo,5,6,11+MIX_BLOCKS*3,12+MIX_BLOCKS*3,
412 GTK_FILL,0,0,2);
413 gtk_table_set_row_spacing(GTK_TABLE(table),6,10);
417 for(i=0;i<MIX_BLOCKS;i++){
418 slider_readout_pair *att=calloc(1,sizeof(*att));
419 slider_readout_pair *del=calloc(1,sizeof(*del));
421 GtkWidget *boxA=gtk_hbox_new(0,0);
422 GtkWidget *boxB=gtk_hbox_new(1,0);
424 GtkWidget *bI=gtk_check_button_new_with_mnemonic("_invert source");
426 GtkWidget *bM=gtk_toggle_button_new_with_label("master");
427 GtkWidget *bA=gtk_toggle_button_new_with_label("revA");
428 GtkWidget *bB=gtk_toggle_button_new_with_label("revB");
429 GtkWidget *h=gtk_hseparator_new();
431 GtkWidget *latt=gtk_label_new(" attenuation ");
432 GtkWidget *ldel=gtk_label_new(" delay ");
433 gtk_misc_set_alignment(GTK_MISC(latt),1,.5);
434 gtk_misc_set_alignment(GTK_MISC(ldel),1,.5);
436 ps->insert_source[i][0]=bM;
437 ps->insert_source[i][1]=bA;
438 ps->insert_source[i][2]=bB;
439 ps->insert_invert[i]=bI;
441 att->s=multibar_slider_new(11,labels_dB,levels_dB,1);
442 del->s=multibar_slider_new(6,labels_del,levels_del,1);
443 att->r=readout_new("+00.0dB");
444 del->r=readout_new("+00.0ms");
445 att->val=&m->insert_att[i];
446 del->val=&m->insert_delay[i];
448 ps->sub[i]=multibar_new(6,labels_dBn,levels_dBn,0,
449 LO_ATTACK|LO_DECAY|HI_DECAY);
451 ps->insert_att[i]=att;
452 ps->insert_del[i]=del;
454 multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
455 multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
457 gtk_box_pack_start(GTK_BOX(boxA),bM,1,1,0);
458 gtk_box_pack_start(GTK_BOX(boxA),bA,1,1,0);
459 gtk_box_pack_start(GTK_BOX(boxA),bB,1,1,0);
461 g_signal_connect (G_OBJECT (bI), "clicked",
462 G_CALLBACK (toggle_callback),
463 (gpointer)&m->insert_invert[i]);
465 g_signal_connect (G_OBJECT (bM), "clicked",
466 G_CALLBACK (toggle_callback),
467 (gpointer)&m->insert_source[i][0]);
468 g_signal_connect (G_OBJECT (bA), "clicked",
469 G_CALLBACK (toggle_callback),
470 (gpointer)&m->insert_source[i][1]);
471 g_signal_connect (G_OBJECT (bB), "clicked",
472 G_CALLBACK (toggle_callback),
473 (gpointer)&m->insert_source[i][2]);
475 for(j=0;j<OUTPUT_CHANNELS;j++){
476 char buffer[80];
477 GtkWidget *b;
479 sprintf(buffer," %d ",j+1);
481 b=gtk_toggle_button_new_with_label(buffer);
482 g_signal_connect (G_OBJECT (b), "clicked",
483 G_CALLBACK (toggle_callback),
484 (gpointer)&m->insert_dest[i][j]);
486 ps->insert_dest[i][j]=b;
488 gtk_box_pack_start(GTK_BOX(boxB),b,1,1,0);
491 gtk_table_attach(GTK_TABLE(table),boxA,0,2,9+i*3,10+i*3,
492 GTK_FILL|GTK_EXPAND,0,0,0);
493 gtk_table_attach(GTK_TABLE(table),boxB,5,6,9+i*3,10+i*3,
494 GTK_FILL|GTK_EXPAND,0,0,0);
495 gtk_table_attach(GTK_TABLE(table),att->s,3,4,8+i*3,9+i*3,
496 GTK_FILL|GTK_EXPAND,0,2,0);
497 gtk_table_attach(GTK_TABLE(table),del->s,3,4,9+i*3,10+i*3,
498 GTK_FILL|GTK_EXPAND,0,2,0);
499 gtk_table_attach(GTK_TABLE(table),att->r,4,5,8+i*3,9+i*3,
500 GTK_FILL|GTK_EXPAND,0,0,0);
501 gtk_table_attach(GTK_TABLE(table),del->r,4,5,9+i*3,10+i*3,
502 GTK_FILL|GTK_EXPAND,0,0,0);
504 gtk_table_attach(GTK_TABLE(table),bI,0,2,8+i*3,9+i*3,
505 0,0,0,0);
506 gtk_table_attach(GTK_TABLE(table),ps->sub[i],5,6,8+i*3,9+i*3,
507 GTK_FILL,0,0,0);
509 gtk_table_attach(GTK_TABLE(table),latt,2,3,8+i*3,9+i*3,
510 GTK_FILL,0,0,0);
511 gtk_table_attach(GTK_TABLE(table),ldel,2,3,9+i*3,10+i*3,
512 GTK_FILL,0,0,0);
514 gtk_table_attach(GTK_TABLE(table),h,0,6,10+i*3,11+i*3,
515 GTK_FILL,0,0,2);
520 gtk_box_pack_start(GTK_BOX(panel->subpanel_box),table,1,1,4);
521 subpanel_show_all_but_toplevel(panel);
523 return ps;
526 void mixpanel_create_channel(postfish_mainpanel *mp,
527 GtkWidget **windowbutton,
528 GtkWidget **activebutton){
529 int i;
530 mix_panels=malloc(input_ch*sizeof(*mix_panels));
532 /* a panel for each channel */
533 for(i=0;i<input_ch;i++){
534 subpanel_generic *panel;
535 char buffer[80];
537 sprintf(buffer,"Mi_xdown block (channel %d)",i+1);
539 panel=subpanel_create(mp,windowbutton[i],activebutton+i,
540 &mixpanel_active[i],
541 &mixpanel_visible[i],
542 buffer,0,i,1);
544 mix_panels[i]=mixpanel_create_helper(mp,panel,mix_set+i,i);
545 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(activebutton[i]),1);
549 void attenpanel_create(postfish_mainpanel *mp,
550 GtkWidget **windowbutton,
551 GtkWidget **activebutton){
552 int i;
553 subpanel_generic *panel=subpanel_create(mp,windowbutton[0],activebutton,
554 mixpanel_active,
555 &atten_visible,
556 "Mi_x Input Delay / Attenuation",
557 0,0,input_ch);
559 GtkWidget *table=gtk_table_new(input_ch*3+2,5,0);
560 atten_panel.master=calloc(input_ch,sizeof(*atten_panel.master));
561 atten_panel.att=calloc(input_ch,sizeof(*atten_panel.att));
562 atten_panel.del=calloc(input_ch,sizeof(*atten_panel.del));
563 atten_panel.panel=panel;
565 for(i=0;i<input_ch;i++){
566 char buffer[80];
567 GtkWidget *l1=gtk_label_new("attenuation ");
568 GtkWidget *l2=gtk_label_new("delay ");
569 GtkWidget *h=gtk_hseparator_new();
571 sprintf(buffer," %d ",i+1);
572 GtkWidget *lN=gtk_label_new(buffer);
573 gtk_widget_set_name(lN,"framelabel");
575 sprintf(buffer,"channel/reverb %d VU",i+1);
576 GtkWidget *lV=gtk_label_new(buffer);
578 slider_readout_pair *att=calloc(1,sizeof(*att));
579 slider_readout_pair *del=calloc(1,sizeof(*del));
581 atten_panel.master[i]=multibar_new(6,labels_dBn,levels_dBn,0,
582 LO_ATTACK|LO_DECAY|HI_DECAY);
583 atten_panel.att[i]=att;
584 atten_panel.del[i]=del;
586 att->s=multibar_slider_new(11,labels_dB,levels_dB,1);
587 att->r=readout_new("+00.0dB");
588 att->val=&mix_set[i].master_att;
590 del->s=multibar_slider_new(6,labels_del,levels_del,1);
591 del->r=readout_new("+00.0ms");
592 del->val=&mix_set[i].master_delay;
594 multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
595 multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
597 multibar_thumb_set(MULTIBAR(att->s),0,0);
598 multibar_thumb_set(MULTIBAR(del->s),0,0);
600 gtk_misc_set_alignment(GTK_MISC(lN),1,.5);
601 gtk_misc_set_alignment(GTK_MISC(l1),1,.5);
602 gtk_misc_set_alignment(GTK_MISC(l2),1,.5);
604 gtk_table_attach(GTK_TABLE(table),lN,0,1,0+i*3,2+i*3,
605 0,0,15,0);
607 gtk_table_attach(GTK_TABLE(table),h,0,5,2+i*3,3+i*3,
608 GTK_FILL|GTK_EXPAND,0,0,2);
610 gtk_table_attach(GTK_TABLE(table),l1,1,2,0+i*3,1+i*3,
611 GTK_FILL|GTK_EXPAND,0,0,0);
612 gtk_table_attach(GTK_TABLE(table),att->s,2,3,0+i*3,1+i*3,
613 GTK_FILL|GTK_EXPAND,0,0,0);
614 gtk_table_attach(GTK_TABLE(table),att->r,3,4,0+i*3,1+i*3,
615 GTK_FILL|GTK_EXPAND,0,0,0);
616 gtk_table_attach(GTK_TABLE(table),atten_panel.master[i],4,5,0+i*3,1+i*3,
617 GTK_FILL,0,0,0);
618 gtk_table_attach(GTK_TABLE(table),lV,4,5,1+i*3,2+i*3,
619 GTK_FILL,0,0,0);
621 gtk_table_attach(GTK_TABLE(table),l2,1,2,1+i*3,2+i*3,
622 GTK_FILL|GTK_EXPAND,0,0,0);
623 gtk_table_attach(GTK_TABLE(table),del->s,2,3,1+i*3,2+i*3,
624 GTK_FILL|GTK_EXPAND,0,0,0);
625 gtk_table_attach(GTK_TABLE(table),del->r,3,4,1+i*3,2+i*3,
626 GTK_FILL|GTK_EXPAND,0,0,0);
630 /* average attenuation slider */
633 GtkWidget *l1=gtk_label_new("attenuation ");
634 GtkWidget *lN=gtk_label_new("Avg");
635 gtk_widget_set_name(lN,"framelabel");
637 atten_panel.average=multibar_slider_new(11,labels_dB,levels_dB,1);
639 multibar_callback(MULTIBAR(atten_panel.average),av_slider_change,&atten_panel);
641 multibar_thumb_set(MULTIBAR(atten_panel.average),0,0);
642 gtk_misc_set_alignment(GTK_MISC(lN),1,.5);
643 gtk_misc_set_alignment(GTK_MISC(l1),1,.5);
645 gtk_table_attach(GTK_TABLE(table),lN,0,1,0+i*3,1+i*3,
646 0,0,15,0);
647 gtk_table_attach(GTK_TABLE(table),l1,1,2,0+i*3,1+i*3,
648 GTK_FILL|GTK_EXPAND,0,0,0);
649 gtk_table_attach(GTK_TABLE(table),atten_panel.average,2,3,0+i*3,1+i*3,
650 GTK_FILL|GTK_EXPAND,0,0,0);
653 gtk_table_set_row_spacing(GTK_TABLE(table),i*3-1,10);
655 av_callback_enter=0; /* enable updates; not done earlier as
656 uncreated widgets would cause a segfualt */
659 gtk_box_pack_start(GTK_BOX(panel->subpanel_box),table,1,1,4);
660 subpanel_show_all_but_toplevel(panel);
664 static float **peakfeed=0;
665 static float **rmsfeed=0;
667 void mixpanel_feedback(int displayit){
668 int i,j;
669 if(!peakfeed){
670 peakfeed=malloc(sizeof(*peakfeed)*(MIX_BLOCKS+5));
671 rmsfeed=malloc(sizeof(*rmsfeed)*(MIX_BLOCKS+5));
673 for(i=0;i<(MIX_BLOCKS+5);i++){
674 peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
675 rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
679 if(pull_mix_feedback(peakfeed,rmsfeed)==1){
680 for(j=0;j<input_ch;j++){
681 for(i=0;i<(MIX_BLOCKS+3);i++){
682 float rms[input_ch+4];
683 float peak[input_ch+4];
685 memset(rms,0,sizeof(rms));
686 memset(peak,0,sizeof(peak));
688 switch(i){
689 case 0:
691 /* master VU w/reverb display (3 channels) */
692 rms[1]=todB(rmsfeed[0][j])*.5;
693 peak[1]=todB(peakfeed[0][j])*.5;
694 rms[2]=todB(rmsfeed[1][j])*.5;
695 peak[2]=todB(peakfeed[1][j])*.5;
696 rms[3]=todB(rmsfeed[2][j])*.5;
697 peak[3]=todB(peakfeed[2][j])*.5;
699 multibar_set(MULTIBAR(atten_panel.master[j]),rms,peak,
700 4,(displayit && atten_visible));
701 break;
703 case 2:
704 case 1:
706 rms[j]=todB(rmsfeed[i+2][j])*.5;
707 peak[j]=todB(peakfeed[i+2][j])*.5;
708 multibar_set(MULTIBAR(mix_panels[j]->place[i-1]),rms,peak,
709 input_ch,(displayit && mixpanel_visible[j]));
710 break;
711 default:
712 rms[j]=todB(rmsfeed[i+2][j])*.5;
713 peak[j]=todB(peakfeed[i+2][j])*.5;
714 multibar_set(MULTIBAR(mix_panels[j]->sub[i-3]),rms,peak,
715 input_ch,(displayit && mixpanel_visible[j]));
716 break;
723 void mixpanel_reset(void){
724 int i,j;
726 for(j=0;j<input_ch;j++){
727 multibar_reset(MULTIBAR(atten_panel.master[j]));
728 multibar_reset(MULTIBAR(mix_panels[j]->place[0]));
729 multibar_reset(MULTIBAR(mix_panels[j]->place[1]));
731 for(i=0;i<MIX_BLOCKS;i++)
732 multibar_reset(MULTIBAR(mix_panels[j]->sub[i]));