Merge r14152 from theora-exp.
[xiph/unicode.git] / postfish / eqpanel.c
blob8bd30f8e87f07b63ff0ed5f82f84a88f1ad102a0
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 "freq.h"
33 #include "eq.h"
34 #include "config.h"
36 typedef struct {
37 GtkWidget *slider;
38 GtkWidget *readout;
39 struct eps *p;
40 int number;
41 } bar;
43 typedef struct eps {
44 subpanel_generic *panel;
45 bar *bars;
46 eq_settings *s;
47 int av_callback_enter;
48 } eq_panel_state;
50 static eq_panel_state *master_panel;
51 static eq_panel_state **channel_panel;
53 static void eqpanel_state_to_config_helper(int bank,eq_settings *s,int A){
54 config_set_integer("eq_active",bank,A,0,0,0,s->panel_active);
55 config_set_vector("eq_settings",bank,A,0,0,eq_freqs,s->settings);
58 void eqpanel_state_to_config(int bank){
59 int i;
60 eqpanel_state_to_config_helper(bank,&eq_master_set,0);
61 for(i=0;i<input_ch;i++)
62 eqpanel_state_to_config_helper(bank,eq_channel_set+i,i+1);
65 static void eqpanel_state_from_config_helper(int bank,eq_settings *s,
66 eq_panel_state *p,int A){
68 int i;
69 config_get_sigat("eq_active",bank,A,0,0,0,&s->panel_active);
70 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->panel->subpanel_activebutton[0]),s->panel_active);
72 config_get_vector("eq_settings",bank,A,0,0,eq_freqs,s->settings);
73 for(i=0;i<eq_freqs;i++)
74 multibar_thumb_set(MULTIBAR(p->bars[i].slider),s->settings[i]*.1,0);
78 void eqpanel_state_from_config(int bank){
79 int i;
80 eqpanel_state_from_config_helper(bank,&eq_master_set,master_panel,0);
81 for(i=0;i<input_ch;i++)
82 eqpanel_state_from_config_helper(bank,eq_channel_set+i,channel_panel[i],i+1);
85 static float determine_average(eq_panel_state *p){
86 bar *b=p->bars;
87 int i;
88 float acc=0;
89 for(i=0;i<eq_freqs;i++)
90 acc+=multibar_get_value(MULTIBAR(b[i].slider),0);
91 return acc/eq_freqs;
94 static void average_change(GtkWidget *w,gpointer in){
95 eq_panel_state *p=(eq_panel_state *)in;
96 if(!p->av_callback_enter){
98 float av=multibar_get_value(MULTIBAR(p->bars[eq_freqs].slider),0);
99 float actual=determine_average(p);
100 int i;
102 p->av_callback_enter=1;
103 for(i=0;i<eq_freqs;i++){
104 float val=multibar_get_value(MULTIBAR(p->bars[i].slider),0) + av - actual;
105 multibar_thumb_set(MULTIBAR(p->bars[i].slider),val,0);
108 p->av_callback_enter=0;
112 static void slider_change(GtkWidget *w,gpointer in){
113 char buffer[80];
114 bar *b=(bar *)in;
115 float val=multibar_get_value(MULTIBAR(b->slider),0);
117 sprintf(buffer,"%+3.0fdB",val);
118 readout_set(READOUT(b->readout),buffer);
120 eq_set(b->p->s,b->number,val);
122 if(!b->p->av_callback_enter){
123 b->p->av_callback_enter=1;
124 float actual=determine_average(b->p);
125 multibar_thumb_set(MULTIBAR(b->p->bars[eq_freqs].slider),actual,0);
126 b->p->av_callback_enter=0;
130 static eq_panel_state *eqpanel_create_helper(postfish_mainpanel *mp,
131 subpanel_generic *panel,
132 eq_settings *es){
134 int i;
135 char *labels[16]={"","110","100","90","80","70","60","50","40",
136 "30","20","10","0","+10","+20","+30"};
137 char *labels2[16]={"","","","","","","60","50","40",
138 "30","20","10","0","+10","+20","+30"};
139 float levels[16]={-120,-110,-100,-90,-80,-70,-60,-50,-40,
140 -30,-20,-10,0,10,20,30};
142 GtkWidget *slidertable=gtk_table_new(eq_freqs+1,3,0);
143 bar *bars=calloc(eq_freqs+1,sizeof(*bars));
144 eq_panel_state *p=calloc(1,sizeof(*p));
146 p->bars=bars;
147 p->s=es;
148 p->panel=panel;
149 p->av_callback_enter=1;
151 for(i=0;i<eq_freqs;i++){
152 const char *labeltext=eq_freq_labels[i];
154 GtkWidget *label=gtk_label_new(labeltext);
155 gtk_widget_set_name(label,"smallmarker");
157 bars[i].readout=readout_new("+00dB");
158 bars[i].slider=multibar_new(16,labels,levels,1,
159 LO_DECAY|HI_DECAY|LO_ATTACK|HI_ATTACK);
160 bars[i].number=i;
161 bars[i].p=p;
163 multibar_callback(MULTIBAR(bars[i].slider),slider_change,bars+i);
164 multibar_thumb_set(MULTIBAR(bars[i].slider),0.,0);
165 multibar_thumb_bounds(MULTIBAR(bars[i].slider),-60,30);
166 multibar_thumb_increment(MULTIBAR(bars[i].slider),1,10);
168 gtk_misc_set_alignment(GTK_MISC(label),1,.5);
170 gtk_table_attach(GTK_TABLE(slidertable),label,0,1,i,i+1,
171 GTK_FILL,0,10,0);
172 gtk_table_attach(GTK_TABLE(slidertable),bars[i].readout,2,3,i,i+1,
173 GTK_FILL,0,0,0);
174 gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,1,2,i,i+1,
175 GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,0,0);
179 GtkWidget *label=gtk_label_new("average");
180 gtk_widget_set_name(label,"smallmarker");
182 bars[i].slider=multibar_slider_new(16,labels2,levels,1);
183 bars[i].number=i;
184 bars[i].p=p;
186 multibar_callback(MULTIBAR(bars[i].slider),average_change,p);
187 multibar_thumb_bounds(MULTIBAR(bars[i].slider),-60,30);
188 multibar_thumb_increment(MULTIBAR(bars[i].slider),1,10);
190 gtk_misc_set_alignment(GTK_MISC(label),1,.5);
192 gtk_table_attach(GTK_TABLE(slidertable),label,0,1,i,i+1,
193 GTK_FILL,0,0,0);
194 gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,1,2,i,i+1,
195 GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,0,0);
199 gtk_box_pack_start(GTK_BOX(panel->subpanel_box),slidertable,1,1,4);
200 subpanel_show_all_but_toplevel(panel);
201 p->av_callback_enter=0;
203 return p;
206 void eqpanel_create_master(postfish_mainpanel *mp,
207 GtkWidget *windowbutton,
208 GtkWidget *activebutton){
210 char *shortcut[]={" e "};
211 subpanel_generic *panel=subpanel_create(mp,windowbutton,&activebutton,
212 &eq_master_set.panel_active,
213 &eq_master_set.panel_visible,
214 "_Equalizer (master)",shortcut,
215 0,1);
217 master_panel=eqpanel_create_helper(mp,panel,&eq_master_set);
220 void eqpanel_create_channel(postfish_mainpanel *mp,
221 GtkWidget **windowbutton,
222 GtkWidget **activebutton){
223 int i;
224 channel_panel=malloc(input_ch*sizeof(*channel_panel));
226 /* a panel for each channel */
227 for(i=0;i<input_ch;i++){
228 subpanel_generic *panel;
229 char buffer[80];
231 sprintf(buffer,"_Equalizer (channel %d)",i+1);
233 panel=subpanel_create(mp,windowbutton[i],activebutton+i,
234 &eq_channel_set[i].panel_active,
235 &eq_channel_set[i].panel_visible,
236 buffer,0,i,1);
238 channel_panel[i]=eqpanel_create_helper(mp,panel,eq_channel_set+i);
243 static float **peakfeed=0;
244 static float **rmsfeed=0;
246 void eqpanel_feedback(int displayit){
247 int i,j;
248 if(!peakfeed){
249 peakfeed=malloc(sizeof(*peakfeed)*eq_freqs);
250 rmsfeed=malloc(sizeof(*rmsfeed)*eq_freqs);
252 for(i=0;i<eq_freqs;i++){
253 peakfeed[i]=malloc(sizeof(**peakfeed)*max(input_ch,OUTPUT_CHANNELS));
254 rmsfeed[i]=malloc(sizeof(**rmsfeed)*max(input_ch,OUTPUT_CHANNELS));
258 if(pull_eq_feedback_master(peakfeed,rmsfeed)==1)
259 for(i=0;i<eq_freqs;i++)
260 multibar_set(MULTIBAR(master_panel->bars[i].slider),rmsfeed[i],peakfeed[i],
261 OUTPUT_CHANNELS,(displayit && eq_master_set.panel_visible));
264 if(pull_eq_feedback_channel(peakfeed,rmsfeed)==1){
265 for(j=0;j<input_ch;j++){
266 for(i=0;i<eq_freqs;i++){
267 float rms[input_ch];
268 float peak[input_ch];
270 memset(rms,0,sizeof(rms));
271 memset(peak,0,sizeof(peak));
272 rms[j]=rmsfeed[i][j];
273 peak[j]=peakfeed[i][j];
275 multibar_set(MULTIBAR(channel_panel[j]->bars[i].slider),rms,peak,
276 input_ch,(displayit && eq_channel_set[j].panel_visible));
282 void eqpanel_reset(void){
283 int i,j;
284 for(i=0;i<eq_freqs;i++)
285 multibar_reset(MULTIBAR(master_panel->bars[i].slider));
287 for(i=0;i<eq_freqs;i++)
288 for(j=0;j<input_ch;j++)
289 multibar_reset(MULTIBAR(channel_panel[j]->bars[i].slider));