new/reworked audio plugins ported from hv72 compressor/multi/reverb, glyph workaround...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / reverb / reverbwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008-2019 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "bcdisplayinfo.h"
22 #include "bchash.h"
23 #include "bcsignals.h"
24 #include "filesystem.h"
25 #include "eqcanvas.h"
26 #include "language.h"
27 #include "reverb.h"
28 #include "reverbwindow.h"
29 #include "theme.h"
30
31 #include <string.h>
32
33 #define TEXT_W xS(90)
34 #define WINDOW_W xS(400)
35 #define WINDOW_H yS(450)
36
37 ReverbWindow::ReverbWindow(Reverb *reverb)
38  : PluginClientWindow(reverb,
39         WINDOW_W, WINDOW_H, WINDOW_W, WINDOW_H, 0)
40 {
41         this->reverb = reverb;
42 }
43
44 ReverbWindow::~ReverbWindow()
45 {
46         for( int i = 0; i < TOTAL_PARAMS; i++ )
47                 delete params[i];
48         delete canvas;
49 }
50
51 void ReverbWindow::create_objects()
52 {
53         int margin = client->get_theme()->widget_border;
54         int x = xS(230), y = margin;
55         int x1 = x + BC_Pot::calculate_w();
56         int x2 = x1 + BC_Pot::calculate_w() + margin;
57         int text_w = get_w() - margin - x2;
58         int height = BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) + margin;
59
60
61         int i = 0;
62         params[i] = new ReverbParam(reverb, this,
63                 margin, x, x2, y, text_w,
64                 0,  // output_i
65                 &reverb->config.level_init, // output_f
66                 0, // output_q
67                 "Initial signal level (db):",
68                 INFINITYGAIN, // min
69                 0); // max
70         params[i]->initialize();
71         i++;
72         y += height;
73
74         params[i] = new ReverbParam(reverb, this,
75                 margin, x1, x2, y, text_w,
76                 &reverb->config.delay_init,  // output_i
77                 0, // output_f
78                 0, // output_q
79                 "ms before reflections:",
80                 0, // min
81                 MAX_DELAY_INIT); // max
82         params[i]->initialize();
83         i++;
84         y += height;
85
86         params[i] = new ReverbParam(reverb, this,
87                 margin, x, x2, y, text_w,
88                 0,  // output_i
89                 &reverb->config.ref_level1, // output_f
90                 0, // output_q
91                 "First reflection level (db):",
92                 INFINITYGAIN, // min
93                 0); // max
94         params[i]->initialize();
95         i++;
96         y += height;
97
98         params[i] = new ReverbParam(reverb, this,
99                 margin, x1, x2, y, text_w,
100                 0,  // output_i
101                 &reverb->config.ref_level2, // output_f
102                 0, // output_q
103                 "Last reflection level (db):",
104                 INFINITYGAIN, // min
105                 0); // max
106         params[i]->initialize();
107         i++;
108         y += height;
109
110         params[i] = new ReverbParam(reverb, this,
111                 margin, x, x2, y, text_w,
112                 &reverb->config.ref_total,  // output_i
113                 0, // output_f
114                 0, // output_q
115                 "Number of reflections:",
116                 MIN_REFLECTIONS, // min
117                 MAX_REFLECTIONS); // max
118         params[i]->initialize();
119         i++;
120         y += height;
121
122         params[i] = new ReverbParam(reverb, this,
123                 margin, x1, x2, y, text_w,
124                 &reverb->config.ref_length,  // output_i
125                 0, // output_f
126                 0, // output_q
127                 "ms of reflections:",
128                 0, // min
129                 MAX_REFLENGTH); // max
130         params[i]->initialize();
131         i++;
132         y += height;
133
134         params[i] = new ReverbParam(reverb, this,
135                 margin, x, x2, y, text_w,
136                 0,  // output_i
137                 0, // output_f
138                 &reverb->config.low, // output_q
139                 "Low freq of bandpass:",
140                 0, // min
141                 0); // max
142         params[i]->initialize();
143         i++;
144         y += height;
145
146         params[i] = new ReverbParam(reverb, this,
147                 margin, x1, x2, y, text_w,
148                 0,  // output_i
149                 0, // output_f
150                 &reverb->config.high, // output_q
151                 "High freq of bandpass:",
152                 0, // min
153                 0); // max
154         params[i]->initialize();
155         i++;
156         y += height;
157
158         params[i] = new ReverbParam(reverb, this,
159                 margin, x, x2, y, text_w,
160                 0,  // output_i
161                 &reverb->config.q, // output_f
162                 0, // output_q
163                 "Steepness of bandpass:",
164                 0.0, // min
165                 1.0); // max
166         params[i]->initialize();
167         params[i]->fpot->set_precision(0.01);
168         i++;
169         y += BC_Pot::calculate_h() + margin;
170
171
172         BC_Title *title;
173         add_subwindow(title = new BC_Title(margin, y, _("Window:")));
174         add_subwindow(size = new ReverbSize(this, reverb,
175                 margin + title->get_w() + margin, y));
176         size->create_objects();
177         size->update(reverb->config.window_size);
178         y += size->get_h() + margin;
179
180         int canvas_x = 0;
181         int canvas_y = y;
182         int canvas_w = get_w() - margin;
183         int canvas_h = get_h() - canvas_y - margin;
184         canvas = new EQCanvas(this,
185                 canvas_x, canvas_y, canvas_w, canvas_h,
186                 INFINITYGAIN, 0.0);
187         canvas->initialize();
188         update();
189
190         show_window();
191 }
192
193 void ReverbWindow::update()
194 {
195         for( int i = 0; i < TOTAL_PARAMS; i++ )
196                 params[i]->update(1, 1);
197         size->update(reverb->config.window_size);
198         update_canvas();
199 }
200
201
202 void ReverbWindow::update_canvas()
203 {
204         double tracking_position = reverb->get_tracking_position();
205         CompressorFreqFrame *frame = (CompressorFreqFrame *)
206                 reverb->get_gui_frame(tracking_position, 1);
207         canvas->update_spectrogram(frame, -1, -1, -1);
208
209 // draw the envelope
210         reverb->calculate_envelope();
211         canvas->draw_envelope(reverb->envelope,
212                 reverb->PluginAClient::project_sample_rate,
213                 reverb->config.window_size, 1, 0);
214         BC_SubWindow *gui = canvas->canvas;
215         gui->flash(1);
216 //printf("ReverbWindow::update_canvas %d\n", __LINE__);
217 }
218
219
220 ReverbSize::ReverbSize(ReverbWindow *window, Reverb *plugin, int x, int y)
221  : BC_PopupMenu(x, y, xS(100), "4096", 1)
222 {
223         this->plugin = plugin;
224         this->window = window;
225 }
226
227 int ReverbSize::handle_event()
228 {
229         plugin->config.window_size = atoi(get_text());
230         plugin->send_configure_change();
231
232         window->update_canvas();
233         return 1;
234 }
235
236 void ReverbSize::create_objects()
237 {
238         add_item(new BC_MenuItem("2048"));
239         add_item(new BC_MenuItem("4096"));
240         add_item(new BC_MenuItem("8192"));
241         add_item(new BC_MenuItem("16384"));
242         add_item(new BC_MenuItem("32768"));
243         add_item(new BC_MenuItem("65536"));
244         add_item(new BC_MenuItem("131072"));
245         add_item(new BC_MenuItem("262144"));
246 }
247
248 void ReverbSize::update(int size)
249 {
250         char string[BCTEXTLEN];
251         sprintf(string, "%d", size);
252         set_text(string);
253 }
254
255
256 ReverbParam::ReverbParam(Reverb *reverb, ReverbWindow *gui,
257         int x, int x2, int x3, int y, int text_w,
258         int *output_i,
259         float *output_f, // floating point output
260         int *output_q,
261         const char *title, float min, float max)
262 {
263         this->output_i = output_i;
264         this->output_f = output_f;
265         this->output_q = output_q;
266         this->title = cstrdup(title);
267         this->reverb = reverb;
268         this->gui = gui;
269         this->x = x;
270         this->x2 = x2;
271         this->x3 = x3;
272         this->y = y;
273         this->text_w = text_w;
274         this->min = min;
275         this->max = max;
276         fpot = 0;
277         ipot = 0;
278         qpot = 0;
279         text = 0;
280 }
281
282 ReverbParam::~ReverbParam()
283 {
284         delete fpot;
285         delete ipot;
286         delete qpot;
287         delete text;
288         delete [] title;
289 }
290
291 void ReverbParam::initialize()
292 {
293         BC_Title *title_;
294         int y2 = y + (BC_Pot::calculate_h() -
295                 BC_Title::calculate_h(gui, _(title), MEDIUMFONT)) / 2;
296         gui->add_tool(title_ = new BC_Title(x, y2, _(title)));
297
298         if( output_f ) gui->add_tool(fpot = new ReverbFPot(this, x2, y));
299         if( output_i ) gui->add_tool(ipot = new ReverbIPot(this, x2, y));
300         if( output_q ) gui->add_tool(qpot = new ReverbQPot(this, x2, y));
301
302         int y3 = y + (BC_Pot::calculate_h() -
303                 BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1)) / 2;
304         if( output_i )
305                 gui->add_tool(text = new ReverbText(this, x3, y3, text_w, *output_i));
306         if( output_f )
307                 gui->add_tool(text = new ReverbText(this, x3, y3, text_w, *output_f));
308         if( output_q )
309                 gui->add_tool(text = new ReverbText(this, x3, y3, text_w, *output_q));
310 }
311
312 void ReverbParam::update(int skip_text, int skip_pot)
313 {
314         if( !skip_text ) {
315                 if( output_i ) text->update((int64_t)*output_i);
316                 if( output_q ) text->update((int64_t)*output_q);
317                 if( output_f ) text->update((float)*output_f);
318         }
319
320         if( !skip_pot ) {
321                 if( ipot ) ipot->update((int64_t)*output_i);
322                 if( qpot ) ipot->update((int64_t)*output_q);
323                 if( fpot ) ipot->update((float)*output_f);
324         }
325 }
326
327
328 ReverbFPot::ReverbFPot(ReverbParam *param, int x, int y)
329  : BC_FPot(x, y, *param->output_f, param->min, param->max)
330 {
331         this->param = param;
332         set_use_caption(0);
333 }
334
335 int ReverbFPot::handle_event()
336 {
337         *param->output_f = get_value();
338         param->update(0, 1);
339         param->reverb->send_configure_change();
340         param->gui->update_canvas();
341         return 1;
342 }
343
344
345 ReverbIPot::ReverbIPot(ReverbParam *param, int x, int y)
346  : BC_IPot(x, y, *param->output_i, (int)param->min, (int)param->max)
347 {
348         this->param = param;
349         set_use_caption(0);
350 }
351
352 int ReverbIPot::handle_event()
353 {
354         *param->output_i = get_value();
355         param->update(0, 1);
356         param->reverb->send_configure_change();
357         param->gui->update_canvas();
358         return 1;
359 }
360
361
362 ReverbQPot::ReverbQPot(ReverbParam *param, int x, int y)
363  : BC_QPot(x, y, *param->output_q)
364 {
365         this->param = param;
366         set_use_caption(0);
367 }
368
369 int ReverbQPot::handle_event()
370 {
371         *param->output_q = get_value();
372         param->update(0, 1);
373         param->reverb->send_configure_change();
374         param->gui->update_canvas();
375         return 1;
376 }
377
378
379 ReverbText::ReverbText(ReverbParam *param, int x, int y, int text_w, int value)
380  : BC_TextBox(x, y, text_w, 1, (int64_t)value, 1, MEDIUMFONT)
381 {
382         this->param = param;
383 }
384
385 ReverbText::ReverbText(ReverbParam *param, int x, int y, int text_w, float value)
386  : BC_TextBox(x, y, text_w, 1, (float)value, 1, MEDIUMFONT, 2)
387 {
388         this->param = param;
389 }
390
391 int ReverbText::handle_event()
392 {
393         if( param->output_i ) *param->output_i = atoi(get_text());
394         if( param->output_f ) *param->output_f = atof(get_text());
395         if( param->output_q ) *param->output_q = atoi(get_text());
396
397         param->update(1, 0);
398         param->reverb->send_configure_change();
399         param->gui->update_canvas();
400         return 1;
401 }
402