new/reworked audio plugins ported from hv72 compressor/multi/reverb, glyph workaround...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / compressortools.h
diff --git a/cinelerra-5.1/cinelerra/compressortools.h b/cinelerra-5.1/cinelerra/compressortools.h
new file mode 100644 (file)
index 0000000..abfb098
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * CINELERRA
+ * Copyright (C) 2008-2019 Adam Williams <broadcast at earthling dot net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ */
+
+
+// Base classes for compressors
+
+#ifndef COMPRESSORTOOLS_H
+#define COMPRESSORTOOLS_H
+
+
+#include "guicast.h"
+#include "pluginaclient.h"
+#include "samples.inc"
+
+
+#define MIN_ATTACK -10
+#define MAX_ATTACK 10
+#define MIN_DECAY 0
+#define MAX_DECAY 255
+#define MIN_TRIGGER 0
+#define MAX_TRIGGER 255
+// range of the meter
+#define MIN_GAIN_CHANGE -20
+#define MAX_GAIN_CHANGE 20
+
+
+class CompressorConfigBase;
+class CompressorPopup;
+
+
+// get sample from trigger buffer
+#define GET_TRIGGER(buffer, offset) \
+double sample = 0; \
+switch(config->input) \
+{ \
+       case CompressorConfigBase::MAX: \
+       { \
+               double max = 0; \
+               for(int channel = 0; channel < channels; channel++) \
+               { \
+                       sample = fabs((buffer)[offset]); \
+                       if(sample > max) max = sample; \
+               } \
+               sample = max; \
+               break; \
+       } \
+ \
+       case CompressorConfigBase::TRIGGER: \
+               sample = fabs(trigger_buffer[offset]); \
+               break; \
+ \
+       case CompressorConfigBase::SUM: \
+       { \
+               double max = 0; \
+               for(int channel = 0; channel < channels; channel++) \
+               { \
+                       sample = fabs((buffer)[offset]); \
+                       max += sample; \
+               } \
+               sample = max; \
+               break; \
+       } \
+}
+
+
+
+
+
+typedef struct
+{
+// DB from min_db - 0
+       double x, y;
+} compressor_point_t;
+
+class BandConfig
+{
+public:
+       BandConfig();
+       virtual ~BandConfig();
+
+       void copy_from(BandConfig *src);
+       int equiv(BandConfig *src);
+       void boundaries(CompressorConfigBase *base);
+       void save_data(FileXML *xml, int number, int do_multiband);
+       void read_data(FileXML *xml, int do_multiband);
+
+       ArrayList<compressor_point_t> levels;
+       int solo;
+       int bypass;
+// units of seconds
+//     double readahead_len;
+       double attack_len;
+       double release_len;
+
+// upper frequency in Hz
+       int freq;
+};
+
+class CompressorConfigBase
+{
+public:
+       CompressorConfigBase(int total_bands);
+       virtual ~CompressorConfigBase();
+
+       virtual void copy_from(CompressorConfigBase &that);
+       virtual int equivalent(CompressorConfigBase &that);
+       void boundaries();
+       
+       void remove_point(int band, int number);
+       int set_point(int band, double x, double y);
+       double calculate_db(int band, double x);
+       double get_x(int band, int number);
+       double get_y(int band, int number);
+       double calculate_gain(int band, double input);
+
+// Calculate linear output from linear input
+       double calculate_output(int band, double x);
+
+// min DB of the graph
+       double min_db;
+// max DB of the graph
+       double max_db;
+
+       BandConfig *bands;
+       int total_bands;
+       int current_band;
+       int trigger;
+       int input;
+       enum
+       {
+               TRIGGER,
+               MAX,
+               SUM
+       };
+       
+       double min_value;
+//     double min_x, min_y;
+//     double max_x, max_y;
+       int smoothing_only;
+};
+
+
+class CompressorCanvasBase : public BC_SubWindow
+{
+public:
+       CompressorCanvasBase(CompressorConfigBase *config, PluginClient *plugin,
+               PluginClientWindow *window, int x, int y, int w, int h);
+       virtual ~CompressorCanvasBase();
+       int is_dragging();
+       int button_press_event();
+       int button_release_event();
+       int cursor_motion_event();
+       void create_objects();
+       void draw_scales();
+       void update();
+       int x_to_y(int band, int x);
+       int db_to_x(double db);
+       int db_to_y(double db);
+       double x_to_db(int x);
+       double y_to_db(int y);
+
+       virtual void update_window();
+
+       enum { NONE, DRAG };
+
+// clickable area of canvas
+       int graph_x, graph_y;
+       int graph_w, graph_h;
+       int current_point;
+       int current_operation;
+       int divisions;
+       int subdivisions;
+       CompressorConfigBase *config;
+       CompressorPopup *menu;
+       PluginClient *plugin;
+       PluginClientWindow *window;
+};
+
+
+#define FREQ_COMPRESSORFRAME 0
+#define GAIN_COMPRESSORFRAME 1
+// used in eqcanvas, compressortools,
+//  plugins: compressor, compressormulti
+class CompressorClientFrame : public PluginClientFrame
+{
+public:
+       CompressorClientFrame();
+       ~CompressorClientFrame();
+       int type, band;
+};
+
+class CompressorFreqFrame : public CompressorClientFrame
+{
+public:
+       CompressorFreqFrame();
+       ~CompressorFreqFrame();
+
+       double freq_max, time_max;
+       double *data;
+       int data_size;
+       int nyquist;
+};
+
+class CompressorGainFrame : public CompressorClientFrame
+{
+public:
+       CompressorGainFrame();
+       ~CompressorGainFrame();
+
+       double gain, level;
+};
+
+class CompressorEngine
+{
+public:
+       CompressorEngine(CompressorConfigBase *config,
+               int band);
+       ~CompressorEngine();
+       
+       void reset();
+       void calculate_ranges(int *attack_samples,
+               int *release_samples,
+               int *preview_samples,
+               int sample_rate);
+       void process(Samples **output_buffer,
+               Samples **input_buffer,
+               int size,
+               int sample_rate,
+               int channels,
+               int64_t start_position);
+
+       CompressorConfigBase *config;
+       int band;
+// the current line segment defining the smooth signal level
+// starting input value of line segment
+       double slope_value1;
+// ending input value of line segment
+       double slope_value2;
+// samples comprising the line segment
+       int slope_samples;
+// samples from the start of the line to the peak that determined the slope
+       int peak_samples;
+// current sample from 0 to slope_samples
+       int slope_current_sample;
+// current value in the line segment
+       double current_value;
+// gain change values to draw on the GUI
+       ArrayList<double> gui_gains;
+// input levels to draw on the GUI
+       ArrayList<double> gui_levels;
+// which second in process() the gui_values came from
+       ArrayList<double> gui_offsets;
+// samples between gui_values.  Set by the user.
+       int gui_frame_samples;
+// temporaries
+       int gui_frame_counter;
+       double gui_max_gain;
+       double gui_max_level;
+};
+
+
+class CompressorCopy : public BC_MenuItem
+{
+public:
+       CompressorCopy(CompressorPopup *popup);
+       ~CompressorCopy();
+       int handle_event();
+       CompressorPopup *popup;
+};
+
+class CompressorPaste : public BC_MenuItem
+{
+public:
+       CompressorPaste(CompressorPopup *popup);
+       ~CompressorPaste();
+       int handle_event();
+       CompressorPopup *popup;
+};
+
+class CompressorClearGraph : public BC_MenuItem
+{
+public:
+       CompressorClearGraph(CompressorPopup *popup);
+       ~CompressorClearGraph();
+       int handle_event();
+       CompressorPopup *popup;
+};
+
+class CompressorPopup : public BC_PopupMenu
+{
+public:
+       CompressorPopup(CompressorCanvasBase *canvas);
+       ~CompressorPopup();
+       
+       void create_objects();
+       
+       
+       CompressorCanvasBase *canvas;
+};
+
+#define GRAPH_BG_COLOR         0x559977
+#define GRAPH_BORDER1_COLOR    0xeeaa44
+#define GRAPH_BORDER2_COLOR    0xeeaaff
+#define GRAPH_GRID_COLOR       0xeeffcc
+#define GRAPH_ACTIVE_COLOR     0x99cc77
+#define GRAPH_INACTIVE_COLOR   0x666688
+
+#endif
+
+
+
+