+++ /dev/null
-
-/*
- * 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);
-}
-
-