Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / plugins / graphic / graphic.C
diff --git a/cinelerra-5.0/plugins/graphic/graphic.C b/cinelerra-5.0/plugins/graphic/graphic.C
deleted file mode 100644 (file)
index 456b12c..0000000
+++ /dev/null
@@ -1,1387 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 1997-2011 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
- * 
- */
-
-#include "bcdisplayinfo.h"
-#include "bcsignals.h"
-#include "clip.h"
-#include "cursors.h"
-#include "bchash.h"
-#include "filexml.h"
-#include "graphic.h"
-#include "keys.h"
-#include "language.h"
-#include "samples.h"
-#include "theme.h"
-#include "units.h"
-#include "vframe.h"
-
-#include <math.h>
-#include <string.h>
-
-
-// Canvas parameters
-#define MAJOR_DIVISIONS 7
-#define MINOR_DIVISIONS 5
-#define LINE_W4 12
-#define LINE_W3 10
-#define LINE_W2 5
-#define LINE_W1 2
-
-
-
-
-
-
-
-
-REGISTER_PLUGIN(GraphicEQ)
-
-
-
-
-
-
-
-GraphicPoint::GraphicPoint()
-{
-       freq = 0;
-       value = 0.0;
-}
-
-
-
-
-
-
-
-
-GraphicConfig::GraphicConfig()
-{
-       window_size = 4096;
-//     wetness = INFINITYGAIN;
-}
-
-GraphicConfig::~GraphicConfig()
-{
-       points.remove_all_objects();
-}
-
-
-int GraphicConfig::equivalent(GraphicConfig &that)
-{
-       if(that.points.size() != points.size() ||
-               window_size != that.window_size) return 0;
-
-       for(int i = 0; i < points.size(); i++)
-       {
-               if(that.points.get(i)->freq != points.get(i)->freq ||
-                       !EQUIV(that.points.get(i)->value, points.get(i)->value))
-                       return 0;
-       }
-
-
-       return 1;
-}
-
-void GraphicConfig::copy_from(GraphicConfig &that)
-{
-       points.remove_all_objects();
-       for(int i = 0; i < that.points.size(); i++)
-       {
-               GraphicPoint *point;
-               points.append(point = new GraphicPoint);
-               point->freq = that.points.get(i)->freq;
-               point->value = that.points.get(i)->value;
-       }
-       
-       window_size = that.window_size;
-}
-
-void GraphicConfig::interpolate(GraphicConfig &prev, 
-       GraphicConfig &next, 
-       int64_t prev_frame, 
-       int64_t next_frame, 
-       int64_t current_frame)
-{
-       double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
-       double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
-
-// Get current set of points from previous configuration
-       copy_from(prev);
-       
-
-// Interpolate between current set of points and next set
-       for(int i = 0; i < MIN(next.points.size(), points.size()); i++)
-       {
-               points.get(i)->freq = (int)(prev.points.get(i)->freq *
-                       prev_scale +
-                       next.points.get(i)->freq *
-                       next_scale);
-               points.get(i)->value = prev.points.get(i)->value *
-                       prev_scale +
-                       next.points.get(i)->value *
-                       next_scale;
-       }
-}
-
-
-void GraphicConfig::delete_point(int number)
-{
-       points.remove_object_number(number);
-}
-
-
-
-
-
-
-
-GraphicCanvas::GraphicCanvas(GraphicEQ *plugin, 
-       GraphicGUI *gui,
-       int x, 
-       int y, 
-       int w, 
-       int h)
- : BC_SubWindow(x,
-       y,
-       w,
-       h,
-       BLACK)
-{
-       this->plugin = plugin;
-       this->gui = gui;
-       state = GraphicCanvas::NONE;
-}
-
-GraphicCanvas::~GraphicCanvas()
-{
-       temp_points.remove_all_objects();
-}
-
-int GraphicCanvas::button_press_event()
-{
-       process(1, 0, 0);
-       if(state == GraphicCanvas::DRAG_POINT)
-               return 1;
-       else 
-               return 0;
-}
-
-int GraphicCanvas::cursor_motion_event()
-{
-       process(0, 1, 0);
-
-       if(state == GraphicCanvas::DRAG_POINT)
-       {
-               return 1;
-       }
-       else
-               return 0;
-}
-
-int GraphicCanvas::button_release_event()
-{
-       if(state == GraphicCanvas::DRAG_POINT && plugin->active_point >= 0)
-       {
-// Delete point if out of order
-               int point_number = plugin->active_point;
-               GraphicPoint *active_point = temp_points.get(point_number);
-
-
-               for(int i = 0; i < temp_points.size(); i++)
-               {
-                       GraphicPoint *point = temp_points.get(i);
-                       if((point->freq <= active_point->freq && i > point_number) ||
-                               (point->freq >= active_point->freq && i < point_number))
-                       {
-                               temp_points.remove_object_number(point_number);
-                               plugin->active_point = -1;
-                               process(0, 0, 1);
-                               break;
-                       }
-               }
-
-               save_temps();
-               plugin->send_configure_change();
-       }
-
-       state = GraphicCanvas::NONE;
-       return 0;
-}
-
-#define BOX_SIZE 10
-
-int GraphicCanvas::freq_to_y(int freq,
-       ArrayList<GraphicPoint*> *points,
-       double *envelope)
-{
-       int center_y = get_h() / 2;
-       double magnitude = plugin->freq_to_magnitude(freq, points, envelope);
-       double magnitude_db = DB::todb(magnitude);
-       if(magnitude_db < -MAXMAGNITUDE) magnitude_db = -MAXMAGNITUDE;
-       int y = (int)(center_y - magnitude_db * center_y / MAXMAGNITUDE);
-//printf("GraphicCanvas::freq_to_y magnitude=%f magnitude_db=%f y=%d\n", 
-//magnitude, magnitude_db, y);
-       return y;
-}
-
-
-void GraphicCanvas::new_temps()
-{
-// Copy configuration from plugin for editing
-       temp_points.remove_all_objects();
-       for(int i = 0; i < plugin->config.points.size(); i++)
-       {
-               GraphicPoint *point = new GraphicPoint;
-               *point = *plugin->config.points.get(i);
-               temp_points.append(point);
-       }
-       
-       plugin->calculate_envelope(&temp_points, temp_envelope);
-}
-
-void GraphicCanvas::save_temps()
-{
-       plugin->config.points.remove_all_objects();
-       for(int i = 0; i < temp_points.size(); i++)
-       {
-               GraphicPoint *point;
-               plugin->config.points.append(point = new GraphicPoint);
-               *point = *temp_points.get(i);
-       }
-}
-
-
-void GraphicCanvas::insert_point(GraphicPoint *point)
-{
-       int done = 0;
-
-       temp_points.append(point);
-       while(!done)
-       {
-               done = 1;
-               for(int i = 0; i < temp_points.size() - 1; i++)
-               {
-                       if(temp_points.get(i)->freq > temp_points.get(i + 1)->freq)
-                       {
-                               GraphicPoint *point = temp_points.get(i);
-                               temp_points.set(i, temp_points.get(i + 1));
-                               temp_points.set(i + 1, point);
-                               done = 0;
-                       }
-               }
-       }
-}
-
-
-void GraphicCanvas::process(int buttonpress, int motion, int draw)
-{
-       int got_button = 0;
-       int center_y = get_h() / 2;
-       int out_of_order = 0;
-       ArrayList<GraphicPoint*> *points;
-       double *envelope;
-       //const int debug = 0;
-
-
-       if(state == GraphicCanvas::NONE)
-       {
-               points = &plugin->config.points;
-               envelope = plugin->envelope;
-       }
-       else
-       {
-               points = &temp_points;
-               envelope = temp_envelope;
-       }
-
-       plugin->calculate_envelope(points, envelope);
-
-
-// spectrogram
-       if(draw)
-       {
-               clear_box(0, 0, get_w(), get_h());
-
-
-               int niquist = plugin->PluginAClient::project_sample_rate / 2;
-               int total_frames = plugin->get_gui_update_frames();
-               GraphicGUIFrame *frame = (GraphicGUIFrame*)plugin->get_gui_frame();
-
-               if(frame)
-               {
-                       delete plugin->last_frame;
-                       plugin->last_frame = frame;
-               }
-               else
-               {
-                       frame = plugin->last_frame;
-               }
-
-// Draw most recent frame
-               if(frame)
-               {
-                       set_color(MEGREY);
-                       int y1 = 0;
-                       int y2 = 0;
-
-
-                       for(int i = 0; i < get_w(); i++)
-                       {
-                               int freq = Freq::tofreq(i * TOTALFREQS / get_w());
-                               int index = (int64_t)freq * (int64_t)frame->window_size / 2 / niquist;
-                               if(index < frame->window_size / 2)
-                               {
-                                       double magnitude = frame->data[index] / 
-                                               frame->freq_max * 
-                                               frame->time_max;
-                                       y2 = (int)(get_h() - 
-                                               (DB::todb(magnitude) - INFINITYGAIN) *
-                                               get_h() / 
-                                               -INFINITYGAIN);
-                                       CLAMP(y2, 0, get_h() - 1);
-                                       if(i > 0)
-                                       {
-                                               draw_line(i - 1, y1, i, y2);
-//printf(" %.0f", frame->data[index]);
-                                       }
-                                       y1 = y2;
-                               }
-                       }
-//printf( "\n");
-
-                       total_frames--;
-               }
-
-
-
-
-
-
-// Delete remaining frames
-               while(total_frames > 0)
-               {
-                       PluginClientFrame *frame = plugin->get_gui_frame();
-
-                       if(frame) delete frame;
-                       total_frames--;
-               }
-       }
-
-
-// Determine if active point is out of order
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = points->get(plugin->active_point);
-               for(int i = 0; i < points->size(); i++)
-               {
-                       if(i == plugin->active_point)
-                       {
-                               if( (i < points->size() - 1 &&
-                                       active_point->freq >= points->get(i + 1)->freq) ||
-                                   (i > 0 &&
-                                       active_point->freq <= points->get(i - 1)->freq) )
-                               {
-                                       out_of_order = 1;
-                               }
-                               break;
-                       }
-               }
-       }
-
-
-       if(motion)
-       {
-               if(state == GraphicCanvas::DRAG_POINT)
-               {
-                       int point_x = get_cursor_x() + x_diff;
-                       int point_y = get_cursor_y() + y_diff;
-                       CLAMP(point_x, 0, get_w());
-                       CLAMP(point_y, 0, get_h());
-                       
-                       int frequency = Freq::tofreq(point_x * TOTALFREQS / get_w());
-                       double magnitude_db = (double)(center_y - point_y) * MAXMAGNITUDE / center_y;
-                       int minfreq = Freq::tofreq(0);
-                       int maxfreq = Freq::tofreq(TOTALFREQS - 1);
-
-                       CLAMP(frequency, minfreq, maxfreq);
-                       CLAMP(magnitude_db, -MAXMAGNITUDE, MAXMAGNITUDE);
-                       if(plugin->active_point >= 0)
-                       {
-                               GraphicPoint *active_point = points->get(plugin->active_point);
-                               active_point->freq = frequency;
-                               active_point->value = magnitude_db;
-                       }
-
-// Redraw with new value
-                       process(0, 0, 1);
-                       save_temps();
-                       plugin->send_configure_change();
-                       gui->update_textboxes();
-                       return;
-               }
-       }
-
-// Magnitude bars
-       if(draw)
-       {
-               set_color(GREEN);
-               set_line_dashes(1);
-               for(int i = 1; i < MAJOR_DIVISIONS; i++)
-               {
-                       int y = i * get_h() / (MAJOR_DIVISIONS - 1);
-                       draw_line(0, y, get_w(), y);
-               }
-               set_line_dashes(0);
-       }
-
-       int y1 = 0;
-       if(draw) set_color(WHITE);
-
-// Control points, cursor change and control point selection
-       int new_cursor = CROSS_CURSOR;
-       for(int i = 0; i < points->size(); i++)
-       {
-               GraphicPoint *point = points->get(i);
-               int x = Freq::fromfreq(point->freq) * get_w() / TOTALFREQS;
-               int y = freq_to_y(point->freq, points, envelope);
-
-               if(draw)
-               {
-                       y1 = y;
-// Draw point under cursor if out of order
-                       if(i == plugin->active_point && out_of_order) 
-                               y1 = get_cursor_y() + y_diff;
-
-                       if(i == plugin->active_point)
-                               draw_box(x - BOX_SIZE / 2, y1 - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
-                       else
-                               draw_rectangle(x - BOX_SIZE / 2, y1 - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
-               }
-
-               if(motion && 
-                       state == GraphicCanvas::NONE &&
-                       is_event_win() && 
-                       cursor_inside())
-               {
-                       if(get_cursor_x() >= x - BOX_SIZE / 2 &&
-                               get_cursor_y() >= y - BOX_SIZE / 2 &&
-                               get_cursor_x() < x + BOX_SIZE / 2 &&
-                               get_cursor_y() < y + BOX_SIZE / 2)
-                       {
-                               new_cursor = UPRIGHT_ARROW_CURSOR;
-                       }
-               }
-               
-               if(buttonpress &&
-                       state == GraphicCanvas::NONE &&
-                       is_event_win() && 
-                       cursor_inside() &&
-                       !got_button)
-               {
-                       if(get_cursor_x() >= x - BOX_SIZE / 2 &&
-                               get_cursor_y() >= y - BOX_SIZE / 2 &&
-                               get_cursor_x() < x + BOX_SIZE / 2 &&
-                               get_cursor_y() < y + BOX_SIZE / 2)
-                       {
-                               plugin->active_point = i;
-                               state = GraphicCanvas::DRAG_POINT;
-                               new_temps();
-                               points = &temp_points;
-                               envelope = temp_envelope;
-
-                               x_diff = x - get_cursor_x();
-                               y_diff = y - get_cursor_y();
-                               got_button = 1;
-                               process(0, 0, 1);
-                               save_temps();
-                               plugin->send_configure_change();
-                               gui->update_textboxes();
-                       }
-               }
-       }
-
-       if(motion && new_cursor != get_cursor())
-       {
-               set_cursor(new_cursor, 0, 1);
-       }
-
-// Envelope line;
-       y1 = 0;
-       set_line_width(2);
-       for(int i = 0; i < get_w(); i++)
-       {
-               int y = freq_to_y(Freq::tofreq(i * TOTALFREQS / get_w()), 
-                       points, 
-                       envelope);
-
-               if(draw)
-               {
-                       if(i > 0) draw_line(i - 1, y1, i, y);
-               }
-
-
-               y1 = y;
-       }
-       set_line_width(1);
-
-       if(buttonpress && !got_button)
-       {
-               if(is_event_win() && cursor_inside())
-               {
-                       GraphicPoint *new_point = new GraphicPoint;
-                       new_point->freq = Freq::tofreq(get_cursor_x() * 
-                               TOTALFREQS / 
-                               get_w());
-                       new_point->value = (double)(center_y - get_cursor_y()) * 
-                               MAXMAGNITUDE / 
-                               center_y;
-                       state = GraphicCanvas::DRAG_POINT;
-                       new_temps();
-                       points = &temp_points;
-                       envelope = temp_envelope;
-
-                       insert_point(new_point);
-                       plugin->active_point = points->number_of(new_point);
-                       x_diff = 0;
-                       y_diff = 0;
-
-// Redraw with new point
-                       process(0, 0, 1);
-                       save_temps();
-                       plugin->send_configure_change();
-                       gui->update_textboxes();
-               }
-       }
-
-
-       if(draw) 
-       {
-               flash();
-       }
-}
-
-
-
-
-
-
-
-
-
-FreqTextBox::FreqTextBox(GraphicEQ *plugin,
-       GraphicGUI *gui,
-       int x,
-       int y,
-       int w)
- : BC_TextBox(x, y, w, 1, "")
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-
-int FreqTextBox::handle_event()
-{
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = plugin->config.points.get(plugin->active_point);
-               if(atoi(get_text()) != active_point->freq)
-               {
-                       active_point->freq = atoi(get_text());
-                       gui->update_canvas();
-                       plugin->send_configure_change();
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-void FreqTextBox::update(int freq)
-{
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = plugin->config.points.get(plugin->active_point);
-               if(atoi(get_text()) != active_point->freq)
-               {
-                       char string[BCTEXTLEN];
-                       sprintf(string, "%d", active_point->freq);
-                       BC_TextBox::update(string);
-               }
-       }
-}
-
-
-
-
-ValueTextBox::ValueTextBox(GraphicEQ *plugin,
-       GraphicGUI *gui,
-       int x,
-       int y,
-       int w)
- : BC_TextBox(x, y, w, 1, "")
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-
-int ValueTextBox::handle_event()
-{
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = plugin->config.points.get(plugin->active_point);
-               if(!EQUIV(atof(get_text()), active_point->value))
-               {
-                       active_point->value = atof(get_text());
-                       gui->update_canvas();
-                       plugin->send_configure_change();
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-void ValueTextBox::update(float value)
-{
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = plugin->config.points.get(plugin->active_point);
-               if(!EQUIV(atof(get_text()), active_point->value))
-               {
-                       char string[BCTEXTLEN];
-                       sprintf(string, "%.04f", active_point->value);
-                       BC_TextBox::update(string);
-               }
-       }
-}
-
-GraphicReset::GraphicReset(GraphicEQ *plugin,
-       GraphicGUI *gui,
-       int x,
-       int y)
- : BC_GenericButton(x, y, _("Reset"))
-{
-       this->plugin = plugin;
-       this->gui = gui;
-}
-
-int GraphicReset::handle_event()
-{
-       plugin->config.points.remove_all_objects();
-       plugin->active_point = -1;
-       gui->update_canvas();
-       gui->update_textboxes();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-GraphicSize::GraphicSize(GraphicGUI *window, GraphicEQ *plugin, int x, int y)
- : BC_PopupMenu(x, y, 100, "4096", 1)
-{
-       this->plugin = plugin;
-       this->window = window;
-}
-
-
-int GraphicSize::handle_event()
-{
-       plugin->config.window_size = atoi(get_text());
-       plugin->send_configure_change();
-
-       window->update_canvas();
-       return 1;
-}
-
-void GraphicSize::create_objects()
-{
-       add_item(new BC_MenuItem("2048"));
-       add_item(new BC_MenuItem("4096"));
-       add_item(new BC_MenuItem("8192"));
-       add_item(new BC_MenuItem("16384"));
-       add_item(new BC_MenuItem("32768"));
-       add_item(new BC_MenuItem("65536"));
-       add_item(new BC_MenuItem("131072"));
-       add_item(new BC_MenuItem("262144"));
-}
-
-void GraphicSize::update(int size)
-{
-       char string[BCTEXTLEN];
-       sprintf(string, "%d", size);
-       set_text(string);
-}
-
-
-
-
-// 
-// 
-// GraphicWetness::GraphicWetness(GraphicGUI *window, GraphicEQ *plugin, int x, int y)
-//  : BC_FPot(x, y, plugin->config.wetness, INFINITYGAIN, 0)
-// {
-//     this->plugin = plugin;
-//     this->window = window;
-// }
-// 
-// int GraphicWetness::handle_event()
-// {
-//     plugin->config.wetness = get_value();
-//     plugin->send_configure_change();
-//     window->update_canvas();
-//     return 1;
-// }
-// 
-// 
-// 
-
-
-
-
-
-
-GraphicGUI::GraphicGUI(GraphicEQ *plugin)
- : PluginClientWindow(plugin, 
-       plugin->w, 
-       plugin->h, 
-       320, 
-       200,
-       1)
-{
-       this->plugin = plugin;
-}
-
-GraphicGUI::~GraphicGUI()
-{
-}
-
-
-void GraphicGUI::create_objects()
-{
-       int margin = plugin->get_theme()->widget_border;
-       int x = get_text_width(SMALLFONT, "-00") + LINE_W4 + margin;
-       int y = margin;
-       int freq_h = get_text_height(SMALLFONT) + LINE_W4;
-
-       add_subwindow(canvas = new GraphicCanvas(plugin,
-               this,
-               x, 
-               y, 
-               get_w() - x - margin, 
-               get_h() - 
-//                     BC_Pot::calculate_h() - 
-                       BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) -
-                       margin * 3 - 
-                       y - 
-                       freq_h));
-       y += canvas->get_h() + freq_h + margin;
-
-//     int x1 = x;
-//     int y1 = y;
-       add_subwindow(freq_title = new BC_Title(x, y, _("Frequency:")));
-       x += freq_title->get_w() + margin;
-       add_subwindow(freq_text = new FreqTextBox(plugin, this, x, y, 100));
-       x += freq_text->get_w() + margin;
-
-       add_subwindow(level_title = new BC_Title(x, y, _("Level:")));
-       x += level_title->get_w() + margin;
-       add_subwindow(value_text = new ValueTextBox(plugin, this, x, y, 100));
-       x += value_text->get_w() + margin;
-
-       add_subwindow(reset = new GraphicReset(plugin, this, x, y));
-       x += reset->get_w() + margin;
-       
-
-//     x = x1;
-//     y += value_text->get_h() + margin;
-
-       add_subwindow(size_title = new BC_Title(x, y, _("Window size:")));
-       x += size_title->get_w() + margin;
-       add_subwindow(size = new GraphicSize(this, plugin, x, y));
-       size->create_objects();
-       size->update(plugin->config.window_size);
-       x += size->get_w() + margin;
-
-//     add_subwindow(title = new BC_Title(x, y, "Wetness:"));
-//     x += title->get_w() + margin;
-//     add_subwindow(wetness = new GraphicWetness(this, plugin, 
-//             x, 
-//             y));
-
-       draw_ticks();
-       update_canvas();
-       show_window();
-}
-
-
-int GraphicGUI::resize_event(int w, int h)
-{
-       int difference = h - get_h();
-       int canvas_xdiff = get_w() - canvas->get_w();
-       int canvas_ydiff = get_h() - canvas->get_h();
-       
-       canvas->reposition_window(canvas->get_x(),
-               canvas->get_y(),
-               w - canvas_xdiff,
-               h - canvas_ydiff);
-       freq_text->reposition_window(freq_text->get_x(),
-               freq_text->get_y() + difference);
-       value_text->reposition_window(value_text->get_x(),
-               value_text->get_y() + difference);
-       freq_title->reposition_window(freq_title->get_x(),
-               freq_title->get_y() + difference);
-       level_title->reposition_window(level_title->get_x(),
-               level_title->get_y() + difference);
-       size_title->reposition_window(size_title->get_x(),
-               size_title->get_y() + difference);
-       reset->reposition_window(reset->get_x(),
-               reset->get_y() + difference);
-       size->reposition_window(size->get_x(),
-               size->get_y() + difference);
-
-       draw_ticks();
-       update_canvas();
-       flash();
-
-       plugin->w = w;
-       plugin->h = h;
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-
-int GraphicGUI::keypress_event()
-{
-       if(get_keypress() == BACKSPACE ||
-               get_keypress() == DELETE)
-       {
-               if(plugin->active_point_exists())
-               {
-                       int point_number = -1;
-                       for(int i = 0; i < plugin->config.points.size(); i++)
-                       {
-                               if(i == plugin->active_point)
-                               {
-                                       point_number = i;
-                                       break;
-                               }
-                       }
-                       
-                       if(point_number >= 0)
-                       {
-                               plugin->config.delete_point(point_number);
-                               canvas->process(0, 0, 1);
-                               plugin->send_configure_change();
-                               return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
-
-void GraphicGUI::draw_ticks()
-{
-       //int x = canvas->get_x() - 5 - get_text_width(SMALLFONT, "-00");
-       int y = canvas->get_y() - 1;
-       int x1 = canvas->get_x() - LINE_W3;
-       int x2 = canvas->get_x() - LINE_W2;
-       int x3 = canvas->get_x() - LINE_W1;
-       char string[BCTEXTLEN];
-
-// Amplitude
-       set_font(SMALLFONT);
-       int major_division = canvas->get_h() / (MAJOR_DIVISIONS - 1);
-       for(int i = 0; i < MAJOR_DIVISIONS; i++)
-       {
-               int current_db = (MAJOR_DIVISIONS - 1 - i) * (MAX_DB - MIN_DB) / (MAJOR_DIVISIONS - 1) + MIN_DB;
-               if(current_db == MIN_DB)
-                       sprintf(string, "oo");
-               else
-               if(current_db <= 0.0)
-                       sprintf(string, "%d", current_db);
-               else
-                       sprintf(string, "+%d", current_db);
-
-               set_color(BLACK);
-               int y1 = y + 1 + i * canvas->get_h() / (MAJOR_DIVISIONS - 1);
-               int x4 = canvas->get_x() - LINE_W4 - get_text_width(SMALLFONT, string);
-               draw_text(x4 + 1, y1 + get_text_ascent(SMALLFONT) / 2 + 1, string);
-               draw_line(x1 + 1, y1 + 1, x3 + 1, y1 + 1);
-               set_color(RED);
-               draw_text(x4, y1 + get_text_ascent(SMALLFONT) / 2, string);
-               draw_line(x1, y1, x3, y1);
-
-
-               if(i < MAJOR_DIVISIONS - 1)
-               {
-                       for(int j = 0; j < MINOR_DIVISIONS; j++)
-                       {
-                               int y2 = y1 + j * major_division / MINOR_DIVISIONS;
-                               set_color(BLACK);
-                               draw_line(x2 + 1, y2 + 1, x3 + 1, y2 + 1);
-                               set_color(RED);
-                               draw_line(x2, y2, x3, y2);
-                       }
-               }
-       }
-
-
-// Frequency
-       for(int i = 0; i <= MAJOR_DIVISIONS; i++)
-       {
-               int freq = Freq::tofreq(i * TOTALFREQS / MAJOR_DIVISIONS);
-               char string[BCTEXTLEN];
-               x1 = canvas->get_x() + i * canvas->get_w() / MAJOR_DIVISIONS;
-               int y1 = canvas->get_y() + canvas->get_h() + LINE_W1 - 1;
-               sprintf(string, "%d", freq);
-               int x2 = x1 - get_text_width(SMALLFONT, string);
-               int y2 = canvas->get_y() + canvas->get_h() + LINE_W2 - 1;
-               int y3 = canvas->get_y() + canvas->get_h() + LINE_W3 - 1;
-               int y4 = canvas->get_y() + canvas->get_h() + get_text_height(SMALLFONT) + LINE_W4 - 1;
-               
-               set_color(BLACK);
-               draw_text(x2 + 1, y4 + 1, string);
-               draw_line(x1 + 1, y3 + 1, x1 + 1, y1 + 1);
-               
-               set_color(RED);
-               draw_text(x2, y4, string);
-               draw_line(x1, y3, x1, y1);
-               
-               if(i < MAJOR_DIVISIONS)
-               {
-                       for(int j = 0; j < MINOR_DIVISIONS; j++)
-                       {
-                               int x3 = (int)(x1 +
-                                       (canvas->get_w() / MAJOR_DIVISIONS) -
-                                       exp(-(double)j * 0.7) *
-                                       (canvas->get_w() / MAJOR_DIVISIONS));
-                               set_color(BLACK);
-                               draw_line(x3 + 1, y2 + 1, x3 + 1, y1 + 1);
-                               set_color(RED);
-                               draw_line(x3, y2, x3, y1);
-                       }
-               }
-       }
-}
-
-void GraphicGUI::update_canvas()
-{
-       canvas->process(0, 0, 1);
-}
-
-void GraphicGUI::update_textboxes()
-{
-       if(plugin->active_point_exists())
-       {
-               GraphicPoint *active_point = plugin->config.points.get(plugin->active_point);
-               freq_text->update(active_point->freq);
-               value_text->update(active_point->value);
-       }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-GraphicEQ::GraphicEQ(PluginServer *server)
- : PluginAClient(server)
-{
-       last_frame = 0; 
-       fft = 0;
-       need_reconfigure = 1;
-       active_point = -1;
-       w = 640;
-       h = 480;
-}
-
-GraphicEQ::~GraphicEQ()
-{
-       
-       delete last_frame;
-       if(fft) delete fft;
-}
-
-
-int GraphicEQ::is_realtime() { return 1; }
-
-const char* GraphicEQ::plugin_title() { return _("EQ Graphic"); }
-
-NEW_WINDOW_MACRO(GraphicEQ, GraphicGUI)
-
-LOAD_CONFIGURATION_MACRO(GraphicEQ, GraphicConfig)
-
-int GraphicEQ::active_point_exists()
-{
-       if(active_point >= 0 && active_point < config.points.size()) return 1;
-       return 0;
-}
-
-
-void GraphicEQ::read_data(KeyFrame *keyframe)
-{
-       FileXML input;
-       int result = 0;
-
-       input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
-       config.points.remove_all_objects();
-
-       while(!result)
-       {
-               result = input.read_tag();
-
-               if(!result)
-               {
-                       if(input.tag.title_is("GRAPHICEQ"))
-                       {
-                               config.window_size = input.tag.get_property("WINDOW_SIZE", config.window_size);
-                               if(is_defaults())
-                               {
-                                       w = input.tag.get_property("W", w);
-                                       h = input.tag.get_property("H", h);
-                               }
-                       }
-                       else
-                       if(input.tag.title_is("POINT"))
-                       {
-                               GraphicPoint *point;
-                               config.points.append(point = new GraphicPoint);
-                               point->freq = input.tag.get_property("X", 0);
-                               point->value = input.tag.get_property("Y", 0.0);
-                       }
-               }
-       }
-
-//     if(!active_point_exists()) active_point = -1;
-}
-
-
-
-
-void GraphicEQ::save_data(KeyFrame *keyframe)
-{
-       FileXML output;
-       output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
-
-       output.tag.set_title("GRAPHICEQ");
-       output.tag.set_property("WINDOW_SIZE", config.window_size);
-       output.tag.set_property("W", w);
-       output.tag.set_property("H", h);
-       output.append_tag();
-       output.tag.set_title("/GRAPHICEQ");
-       output.append_tag();
-       output.append_newline();
-
-       for(int i = 0; i < config.points.total; i++)
-       {
-               output.tag.set_title("POINT");
-               output.tag.set_property("X", config.points.values[i]->freq);
-               output.tag.set_property("Y", config.points.values[i]->value);
-               output.append_tag();
-               output.tag.set_title("/POINT");
-               output.append_tag();
-               output.append_newline();
-       }
-       
-       output.terminate_string();
-}
-
-
-void GraphicEQ::update_gui()
-{
-       if(thread)
-       {
-               if(load_configuration() && 
-                       ((GraphicGUI*)thread->window)->canvas->state != GraphicCanvas::DRAG_POINT)
-               {
-                       ((GraphicGUI*)thread->window)->lock_window("GraphicEQ::update_gui");
-                       ((GraphicGUI*)thread->window)->update_canvas();
-                       ((GraphicGUI*)thread->window)->update_textboxes();
-                       ((GraphicGUI*)thread->window)->unlock_window();
-               }
-               else
-               {
-                       int total_frames = get_gui_update_frames();
-//printf("ParametricEQ::update_gui %d %d\n", __LINE__, total_frames);
-                       if(total_frames)
-                       {
-                               ((GraphicGUI*)thread->window)->lock_window("GraphicEQ::update_gui");
-                               ((GraphicGUI*)thread->window)->update_canvas();
-                               ((GraphicGUI*)thread->window)->unlock_window();
-                       }
-               }
-       }
-}
-
-void GraphicEQ::reconfigure()
-{
-       if(fft && fft->window_size != config.window_size)
-       {
-               delete fft;
-               fft = 0;
-       }
-       
-       if(!fft)
-       {
-               fft = new GraphicFFT(this);
-               fft->initialize(config.window_size);
-       }
-
-       calculate_envelope(&config.points, envelope);
-       
-       for(int i = 0; i < config.window_size / 2; i++)
-       {
-               if(envelope[i] < 0) envelope[i] = 0;
-       }
-
-       need_reconfigure = 0;
-}
-
-int GraphicEQ::process_buffer(int64_t size, 
-       Samples *buffer, 
-       int64_t start_position,
-       int sample_rate)
-{
-       need_reconfigure |= load_configuration();
-       if(need_reconfigure) reconfigure();
-       
-       fft->process_buffer(start_position, size, buffer, get_direction());
-
-
-       return 0;
-}
-
-
-double GraphicEQ::freq_to_magnitude(double frequency,
-       ArrayList<GraphicPoint*> *points,
-       double *envelope)
-{
-// Calculate using control points
-       for(int i = 0; i < points->size(); i++)
-       {
-               GraphicPoint *point = points->get(i);
-               if(point->freq == (int)frequency)
-               {
-                       return DB::fromdb(point->value);
-               }
-       }
-
-
-       int nyquist = PluginAClient::project_sample_rate / 2;
-       int slot = (int)(frequency * config.window_size / 2 / nyquist);
-       if(slot >= config.window_size / 2) slot = config.window_size / 2 - 1;
-//printf("GraphicEQ::freq_to_db %d %f\n", slot, envelope[slot]);
-       return envelope[slot];
-}
-
-
-void GraphicEQ::calculate_envelope(ArrayList<GraphicPoint*> *points,
-               double *envelope)
-{
-       int niquist = PluginAClient::project_sample_rate / 2;
-
-// Make temporary list of just points in order
-       ArrayList<GraphicPoint*> temp_points;
-       for(int i = 0; i < points->size(); i++)
-       {
-               temp_points.append(points->get(i));
-       }
-
-       for(int i = 0; i < temp_points.size(); i++)
-       {
-               GraphicPoint *point = temp_points.get(i);
-               if(i == active_point) 
-               {
-                       GraphicPoint *prev_point = 0;
-                       GraphicPoint *next_point = 0;
-                       if(i >= 1) prev_point = temp_points.get(i - 1);
-                       if(i < temp_points.size() - 1) next_point = temp_points.get(i + 1);
-                       if( (prev_point && prev_point->freq >= point->freq) ||
-                               (next_point && next_point->freq <= point->freq) )
-                               temp_points.remove_number(i);
-                       break;
-               }
-       }
-
-
-// Join each point
-       if(temp_points.size())
-       {
-               GraphicPoint *first_point = temp_points.get(0);
-               GraphicPoint *last_point = temp_points.get(temp_points.size() - 1);
-               for(int i = 0; i < config.window_size / 2; i++)
-               {
-                       int freq = i * niquist / (config.window_size / 2);
-                       if(freq <= first_point->freq)
-                               envelope[i] = first_point->value;
-                       else
-                       if(freq >= last_point->freq)
-                               envelope[i] = last_point->value;
-                       else
-                       {
-                               GraphicPoint *point1 = first_point;
-                               GraphicPoint *point2 = last_point;
-                               for(int j = 0; j < temp_points.size(); j++)
-                               {
-                                       if(temp_points.get(j)->freq <= freq)
-                                               point1 = temp_points.get(j);
-                                       else
-                                       {
-                                               point2 = temp_points.get(j);
-                                               break;
-                                       }
-                               }
-                               
-                               if(point2->freq != point1->freq)
-                               {
-                                       int freqslot1 = Freq::fromfreq(point1->freq);
-                                       int freqslot2 = Freq::fromfreq(point2->freq);
-                                       int freqslot = Freq::fromfreq(freq);
-                               
-                                       envelope[i] = (double)(freqslot - freqslot1) *
-                                               (point2->value - point1->value) / 
-                                               (freqslot2 - freqslot1) +
-                                               point1->value;
-                               }
-                               else
-                                       envelope[i] = point1->value;
-                       }
-
-
-                       if(envelope[i] < MIN_DB + 0.01) 
-                               envelope[i] = 0;
-                       else
-                               envelope[i] = DB::fromdb(envelope[i]);
-               }
-       }
-       else
-       {
-               for(int i = 0; i < config.window_size / 2; i++)
-               {
-                       envelope[i] = 1.0;
-               }
-       }
-}
-
-
-
-
-GraphicGUIFrame::GraphicGUIFrame(int window_size, int sample_rate)
- : PluginClientFrame(window_size / 2, window_size / 2, sample_rate)
-{
-       data = new double[window_size / 2];
-       freq_max = 0;
-       time_max = 0;
-       this->window_size = window_size;
-}
-
-GraphicGUIFrame::~GraphicGUIFrame()
-{
-       delete [] data;
-}
-
-
-
-
-
-
-GraphicFFT::GraphicFFT(GraphicEQ *plugin)
- : CrossfadeFFT()
-{
-       this->plugin = plugin;
-}
-
-GraphicFFT::~GraphicFFT()
-{
-}
-
-
-int GraphicFFT::signal_process()
-{
-// Create new frame for updating GUI
-       frame = new GraphicGUIFrame(window_size, 
-               plugin->PluginAClient::project_sample_rate);
-       plugin->add_gui_frame(frame);
-
-       double freq_max = 0;
-       for(int i = 0; i < window_size / 2; i++)
-       {
-               double result = plugin->envelope[i] * sqrt(freq_real[i] * freq_real[i] + freq_imag[i] * freq_imag[i]);
-               double angle = atan2(freq_imag[i], freq_real[i]);
-               freq_real[i] = result * cos(angle);
-               freq_imag[i] = result * sin(angle);
-               frame->data[i] = result;
-               if(result > freq_max) freq_max = result;
-       }
-       frame->freq_max = freq_max;
-
-       symmetry(window_size, freq_real, freq_imag);
-
-       return 0;
-}
-
-int GraphicFFT::post_process()
-{
-       double time_max = 0;
-       for(int i = 0; i < window_size; i++)
-       {
-               if(output_real[i] > time_max) time_max = output_real[i];
-       }
-       frame->time_max = time_max;
-       return 0;
-}
-
-
-
-int GraphicFFT::read_samples(int64_t output_sample, 
-       int samples, 
-       Samples *buffer)
-{
-       return plugin->read_samples(buffer,
-               0,
-               plugin->get_samplerate(),
-               output_sample,
-               samples);
-}
-
-