new/reworked audio plugins ported from hv72 compressor/multi/reverb, glyph workaround...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / eqcanvas.C
diff --git a/cinelerra-5.1/cinelerra/eqcanvas.C b/cinelerra-5.1/cinelerra/eqcanvas.C
new file mode 100644 (file)
index 0000000..2402888
--- /dev/null
@@ -0,0 +1,248 @@
+#include "clip.h"
+#include "eqcanvas.h"
+#include "mwindow.h"
+#include "pluginaclient.h"
+#include "theme.h"
+
+#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
+
+EQCanvas::EQCanvas(BC_WindowBase *parent,
+               int x, int y, int w, int h,
+               float min_db, float max_db)
+{
+       this->parent = parent;
+       this->x = x;  this->y = y;
+       this->w = w;  this->h = h;
+       this->min_db = min_db;
+       this->max_db = max_db;
+       canvas = 0;
+
+       minor_divisions = 5;
+       freq_divisions = 5;
+}
+
+EQCanvas::~EQCanvas()
+{
+       delete canvas;
+}
+
+void EQCanvas::initialize()
+{
+       int big_xtick = xS(10), big_ytick = yS(10);
+       int small_xtick = xS(5), small_ytick = yS(5);
+       int tiny_xtick = xS(2);
+       int db_width = parent->get_text_width(SMALLFONT, "-00", -1) + big_xtick;
+       int freq_height = parent->get_text_ascent(SMALLFONT);
+
+       canvas_x = x + db_width;
+       canvas_y = y;
+       canvas_w = w - db_width;
+       canvas_h = h - freq_height - big_ytick;
+       parent->add_subwindow(canvas = new BC_SubWindow(
+               canvas_x, canvas_y, canvas_w, canvas_h, BLACK));
+
+// Draw canvas titles
+// DB
+       parent->set_font(SMALLFONT);
+       int ascent = parent->get_text_ascent(SMALLFONT);
+// DB per minor division
+       db_per_division = 1;
+       pixels_per_division = (float)canvas_h / (max_db - min_db) * db_per_division;
+// increase the DB per minor division until they fit
+//printf("EQCanvas::initialize %d pixels_per_division=%f\n", __LINE__, pixels_per_division);
+       while( pixels_per_division < 5 ) {
+               db_per_division *= 2;
+               pixels_per_division = (float)canvas_h / (max_db - min_db) * db_per_division;
+       }
+       total_divisions = (int)((max_db - min_db) / db_per_division);
+
+       char string[BCTEXTLEN];
+       for( int i = 0; i <= total_divisions; i++ ) {
+               int y1 = canvas_y + (int)(i * pixels_per_division);
+               int y2 = y1 + ascent;
+               int x2 = canvas_x - big_xtick;
+               int x3 = canvas_x - tiny_xtick;
+               int x4 = x3 - small_xtick;
+
+               if( !(i % minor_divisions) ||
+                       i == total_divisions ) {
+                       if( i == total_divisions ) {
+                               sprintf(string, "oo");
+                       }
+                       else {
+                               sprintf(string, "%d", (int)(max_db - i * db_per_division));
+                       }
+
+                       parent->set_color(BLACK);
+                       int text_w = parent->get_text_width(SMALLFONT, string, -1);
+                       int x1 = canvas_x - big_xtick - text_w;
+                       parent->set_color(parent->get_resources()->default_text_color);
+                       parent->draw_text(x1, y2, string);
+                       parent->draw_line(x2, y1, x3, y1);
+               }
+               else {
+                       parent->draw_line(x4, y1, x3, y1);
+               }
+       }
+
+// freq
+       for( int i = 0; i <= freq_divisions; i++ ) {
+               int freq = Freq::tofreq(i * TOTALFREQS / freq_divisions);
+               sprintf(string, "%d", freq);
+               int x1 = canvas_x + i * canvas_w / freq_divisions;
+               int x2 = x1 - parent->get_text_width(SMALLFONT, string);
+               int y1 = canvas_y + canvas_h;
+               int y2 = y1 + big_ytick;
+               int y3 = y1 + small_ytick;
+               int y4 = y2 + parent->get_text_ascent(SMALLFONT);
+
+//             parent->set_color(BLACK);
+//             parent->draw_text(x2 + 1, y4 + 1, string);
+//             parent->draw_line(x1 + 1, y1 + 1, x1 + 1, y2 + 1);
+//             parent->set_color(RED);
+               parent->set_color(parent->get_resources()->default_text_color);
+               parent->draw_text(x2, y4, string);
+               parent->draw_line(x1, y1, x1, y2);
+
+               if( i < freq_divisions ) {
+                       for( int j = 0; j < minor_divisions; j++ ) {
+                               int x3 = (int)(x1 +
+                                       (canvas_w / freq_divisions) -
+                                       exp(-(double)j * 0.7) *
+                                       (canvas_w / freq_divisions));
+//                             parent->set_color(BLACK);
+//                             parent->draw_line(x3 + 1, y1 + 1, x3 + 1, y3 + 1);
+//                             parent->set_color(RED);
+                               parent->set_color(parent->get_resources()->default_text_color);
+                               parent->draw_line(x3, y1, x3, y3);
+                       }
+               }
+       }
+
+       draw_grid();
+}
+
+
+void EQCanvas::draw_grid()
+{
+       canvas->set_line_dashes(1);
+       canvas->set_color(graph_grid_color);
+       for( int i = minor_divisions; i < total_divisions; i += minor_divisions ) {
+               int y = (int)(i * pixels_per_division);
+               canvas->draw_line(0, y, canvas_w, y);
+       }
+//     for( int i = 1; i < major_divisions; i++ ) {
+//             int y = canvas_h - i * canvas_h / major_divisions;
+//             canvas->draw_line(0, y, canvas_w, y);
+//     }
+       for( int i = 1; i < freq_divisions; i++ ) {
+               int x = i * canvas_w / freq_divisions;
+               canvas->draw_line(x, 0, x, canvas_h);
+       }
+       canvas->set_line_dashes(0);
+}
+
+void EQCanvas::update_spectrogram(CompressorFreqFrame *frame,
+               int offset, int size, int window_size)
+{
+//if( frame ) printf("EQCanvas::update_spectrogram %d frame->freq_max=%f frame->data=%p\n",
+// __LINE__, frame->freq_max, frame->data);
+       canvas->set_color(graph_bg_color);
+       canvas->draw_box(0, 0, canvas->get_w(), canvas->get_h());
+       draw_grid();
+
+// Draw it
+       if( frame && !EQUIV(frame->freq_max, 0.0) && frame->data ) {
+               int y1 = 0, y2 = 0;
+               if( offset < 0 ) {
+                       offset = 0;
+                       size = frame->data_size;
+                       window_size = frame->data_size * 2;
+               }
+
+               canvas->set_color(graph_inactive_color);
+               if( !EQUIV(frame->freq_max, 0) ) {
+                       for( int i = 0; i < canvas->get_w(); i++ ) {
+                               int freq = Freq::tofreq(i * TOTALFREQS / canvas->get_w());
+
+                               if( freq < frame->nyquist ) {
+                                       int index = offset +
+                                               (int64_t)freq * (int64_t)window_size / 2 /
+                                               frame->nyquist;
+
+                                       if( index < frame->data_size ) {
+                                               double magnitude = frame->data[index] /
+                                                       frame->freq_max * frame->time_max;
+
+                                               y2 = (int)(canvas->get_h() -
+                                                       (DB::todb(magnitude) - INFINITYGAIN) *
+                                                       canvas->get_h() /
+                                                       -INFINITYGAIN);
+                                               CLAMP(y2, 0, canvas->get_h() - 1);
+                                               if( i > 0 ) {
+                                                       canvas->draw_line(i - 1, y1, i, y2);
+                                               }
+                                               y1 = y2;
+                                       }
+                               }
+                               else {
+//                                      printf("EQCanvas::update_spectrogram %d i=%d freq=%d nyquist=%d\n",
+//                                              __LINE__, i, freq, frame->nyquist);
+                               }
+                       }
+               }
+       }
+
+}
+
+
+void EQCanvas::draw_envelope(double *envelope,
+               int samplerate, int window_size, int is_top, int flash_it)
+{
+       int niquist = samplerate / 2;
+
+       if( is_top ) {
+               canvas->set_color(graph_active_color);
+               canvas->set_line_width(2);
+       }
+       else {
+               canvas->set_color(graph_inactive_color);
+               canvas->set_line_width(1);
+       }
+
+       int y1;
+       for( int i = 0; i < canvas->get_w(); i++ ) {
+               int freq = Freq::tofreq(i * TOTALFREQS / canvas->get_w());
+               int index = (int64_t)freq * (int64_t)window_size / 2 / niquist;
+               if( freq < niquist && index < window_size / 2 ) {
+                       double mag = envelope[index];
+                       int y2 = (int)(DB::todb(mag) * canvas->get_h() / INFINITYGAIN);
+
+                       if( y2 >= canvas->get_h() ) {
+                               y2 = canvas->get_h() - 1;
+                       }
+
+                       if( i > 0 ) {
+                               canvas->draw_line(i - 1, y1, i, y2);
+                       }
+                       y1 = y2;
+               }
+               else
+               if( i > 0 ) {
+                       int y2 = canvas->get_h() - 1;
+                       canvas->draw_line(i - 1, y1, i, y2);
+                       y1 = y2;
+               }
+       }
+
+       canvas->set_line_width(1);
+       if( flash_it ) {
+               canvas->flash(1);
+       }
+}
+