new/reworked audio plugins ported from hv72 compressor/multi/reverb, glyph workaround...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / compressortools.h
1 /*
2  * CINELERRA
3  * Copyright (C) 2008-2019 Adam Williams <broadcast at earthling dot net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * 
19  */
20
21
22 // Base classes for compressors
23
24 #ifndef COMPRESSORTOOLS_H
25 #define COMPRESSORTOOLS_H
26
27
28 #include "guicast.h"
29 #include "pluginaclient.h"
30 #include "samples.inc"
31
32
33 #define MIN_ATTACK -10
34 #define MAX_ATTACK 10
35 #define MIN_DECAY 0
36 #define MAX_DECAY 255
37 #define MIN_TRIGGER 0
38 #define MAX_TRIGGER 255
39 // range of the meter
40 #define MIN_GAIN_CHANGE -20
41 #define MAX_GAIN_CHANGE 20
42
43
44 class CompressorConfigBase;
45 class CompressorPopup;
46
47
48 // get sample from trigger buffer
49 #define GET_TRIGGER(buffer, offset) \
50 double sample = 0; \
51 switch(config->input) \
52 { \
53         case CompressorConfigBase::MAX: \
54         { \
55                 double max = 0; \
56                 for(int channel = 0; channel < channels; channel++) \
57                 { \
58                         sample = fabs((buffer)[offset]); \
59                         if(sample > max) max = sample; \
60                 } \
61                 sample = max; \
62                 break; \
63         } \
64  \
65         case CompressorConfigBase::TRIGGER: \
66                 sample = fabs(trigger_buffer[offset]); \
67                 break; \
68  \
69         case CompressorConfigBase::SUM: \
70         { \
71                 double max = 0; \
72                 for(int channel = 0; channel < channels; channel++) \
73                 { \
74                         sample = fabs((buffer)[offset]); \
75                         max += sample; \
76                 } \
77                 sample = max; \
78                 break; \
79         } \
80 }
81
82
83
84
85
86 typedef struct
87 {
88 // DB from min_db - 0
89         double x, y;
90 } compressor_point_t;
91
92 class BandConfig
93 {
94 public:
95         BandConfig();
96         virtual ~BandConfig();
97
98         void copy_from(BandConfig *src);
99         int equiv(BandConfig *src);
100         void boundaries(CompressorConfigBase *base);
101         void save_data(FileXML *xml, int number, int do_multiband);
102         void read_data(FileXML *xml, int do_multiband);
103
104         ArrayList<compressor_point_t> levels;
105         int solo;
106         int bypass;
107 // units of seconds
108 //      double readahead_len;
109         double attack_len;
110         double release_len;
111
112 // upper frequency in Hz
113         int freq;
114 };
115
116 class CompressorConfigBase
117 {
118 public:
119         CompressorConfigBase(int total_bands);
120         virtual ~CompressorConfigBase();
121
122         virtual void copy_from(CompressorConfigBase &that);
123         virtual int equivalent(CompressorConfigBase &that);
124         void boundaries();
125         
126         void remove_point(int band, int number);
127         int set_point(int band, double x, double y);
128         double calculate_db(int band, double x);
129         double get_x(int band, int number);
130         double get_y(int band, int number);
131         double calculate_gain(int band, double input);
132
133 // Calculate linear output from linear input
134         double calculate_output(int band, double x);
135
136 // min DB of the graph
137         double min_db;
138 // max DB of the graph
139         double max_db;
140
141         BandConfig *bands;
142         int total_bands;
143         int current_band;
144         int trigger;
145         int input;
146         enum
147         {
148                 TRIGGER,
149                 MAX,
150                 SUM
151         };
152         
153         double min_value;
154 //      double min_x, min_y;
155 //      double max_x, max_y;
156         int smoothing_only;
157 };
158
159
160 class CompressorCanvasBase : public BC_SubWindow
161 {
162 public:
163         CompressorCanvasBase(CompressorConfigBase *config, PluginClient *plugin,
164                 PluginClientWindow *window, int x, int y, int w, int h);
165         virtual ~CompressorCanvasBase();
166         int is_dragging();
167         int button_press_event();
168         int button_release_event();
169         int cursor_motion_event();
170         void create_objects();
171         void draw_scales();
172         void update();
173         int x_to_y(int band, int x);
174         int db_to_x(double db);
175         int db_to_y(double db);
176         double x_to_db(int x);
177         double y_to_db(int y);
178
179         virtual void update_window();
180
181         enum { NONE, DRAG };
182
183 // clickable area of canvas
184         int graph_x, graph_y;
185         int graph_w, graph_h;
186         int current_point;
187         int current_operation;
188         int divisions;
189         int subdivisions;
190         CompressorConfigBase *config;
191         CompressorPopup *menu;
192         PluginClient *plugin;
193         PluginClientWindow *window;
194 };
195
196
197 #define FREQ_COMPRESSORFRAME 0
198 #define GAIN_COMPRESSORFRAME 1
199 // used in eqcanvas, compressortools,
200 //  plugins: compressor, compressormulti
201 class CompressorClientFrame : public PluginClientFrame
202 {
203 public:
204         CompressorClientFrame();
205         ~CompressorClientFrame();
206         int type, band;
207 };
208
209 class CompressorFreqFrame : public CompressorClientFrame
210 {
211 public:
212         CompressorFreqFrame();
213         ~CompressorFreqFrame();
214
215         double freq_max, time_max;
216         double *data;
217         int data_size;
218         int nyquist;
219 };
220
221 class CompressorGainFrame : public CompressorClientFrame
222 {
223 public:
224         CompressorGainFrame();
225         ~CompressorGainFrame();
226
227         double gain, level;
228 };
229
230 class CompressorEngine
231 {
232 public:
233         CompressorEngine(CompressorConfigBase *config,
234                 int band);
235         ~CompressorEngine();
236         
237         void reset();
238         void calculate_ranges(int *attack_samples,
239                 int *release_samples,
240                 int *preview_samples,
241                 int sample_rate);
242         void process(Samples **output_buffer,
243                 Samples **input_buffer,
244                 int size,
245                 int sample_rate,
246                 int channels,
247                 int64_t start_position);
248
249         CompressorConfigBase *config;
250         int band;
251 // the current line segment defining the smooth signal level
252 // starting input value of line segment
253         double slope_value1;
254 // ending input value of line segment
255         double slope_value2;
256 // samples comprising the line segment
257         int slope_samples;
258 // samples from the start of the line to the peak that determined the slope
259         int peak_samples;
260 // current sample from 0 to slope_samples
261         int slope_current_sample;
262 // current value in the line segment
263         double current_value;
264 // gain change values to draw on the GUI
265         ArrayList<double> gui_gains;
266 // input levels to draw on the GUI
267         ArrayList<double> gui_levels;
268 // which second in process() the gui_values came from
269         ArrayList<double> gui_offsets;
270 // samples between gui_values.  Set by the user.
271         int gui_frame_samples;
272 // temporaries
273         int gui_frame_counter;
274         double gui_max_gain;
275         double gui_max_level;
276 };
277
278
279 class CompressorCopy : public BC_MenuItem
280 {
281 public:
282         CompressorCopy(CompressorPopup *popup);
283         ~CompressorCopy();
284         int handle_event();
285         CompressorPopup *popup;
286 };
287
288 class CompressorPaste : public BC_MenuItem
289 {
290 public:
291         CompressorPaste(CompressorPopup *popup);
292         ~CompressorPaste();
293         int handle_event();
294         CompressorPopup *popup;
295 };
296
297 class CompressorClearGraph : public BC_MenuItem
298 {
299 public:
300         CompressorClearGraph(CompressorPopup *popup);
301         ~CompressorClearGraph();
302         int handle_event();
303         CompressorPopup *popup;
304 };
305
306 class CompressorPopup : public BC_PopupMenu
307 {
308 public:
309         CompressorPopup(CompressorCanvasBase *canvas);
310         ~CompressorPopup();
311         
312         void create_objects();
313         
314         
315         CompressorCanvasBase *canvas;
316 };
317
318 #define GRAPH_BG_COLOR          0x559977
319 #define GRAPH_BORDER1_COLOR     0xeeaa44
320 #define GRAPH_BORDER2_COLOR     0xeeaaff
321 #define GRAPH_GRID_COLOR        0xeeffcc
322 #define GRAPH_ACTIVE_COLOR      0x99cc77
323 #define GRAPH_INACTIVE_COLOR    0x666688
324
325 #endif
326
327
328
329