3 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "pluginaclient.h"
27 #define graph_bg_color 0x559977
28 #define graph_border1_color 0xeeaa44
29 #define graph_border2_color 0xeeaaff
30 #define graph_grid_color 0xeeffcc
31 #define graph_active_color 0x99cc77
32 #define graph_inactive_color 0x666688
34 EQCanvas::EQCanvas(BC_WindowBase *parent,
35 int x, int y, int w, int h,
36 float min_db, float max_db)
38 this->parent = parent;
39 this->x = x; this->y = y;
40 this->w = w; this->h = h;
41 this->min_db = min_db;
42 this->max_db = max_db;
54 void EQCanvas::initialize()
56 int big_xtick = xS(10), big_ytick = yS(10);
57 int small_xtick = xS(5), small_ytick = yS(5);
58 int tiny_xtick = xS(2);
59 int db_width = parent->get_text_width(SMALLFONT, "-00", -1) + big_xtick;
60 int freq_height = parent->get_text_ascent(SMALLFONT);
62 canvas_x = x + db_width;
64 canvas_w = w - db_width;
65 canvas_h = h - freq_height - big_ytick;
66 parent->add_subwindow(canvas = new BC_SubWindow(
67 canvas_x, canvas_y, canvas_w, canvas_h, BLACK));
71 parent->set_font(SMALLFONT);
72 int ascent = parent->get_text_ascent(SMALLFONT);
73 // DB per minor division
75 pixels_per_division = (float)canvas_h / (max_db - min_db) * db_per_division;
76 // increase the DB per minor division until they fit
77 //printf("EQCanvas::initialize %d pixels_per_division=%f\n", __LINE__, pixels_per_division);
78 while( pixels_per_division < 5 ) {
80 pixels_per_division = (float)canvas_h / (max_db - min_db) * db_per_division;
82 total_divisions = (int)((max_db - min_db) / db_per_division);
84 char string[BCTEXTLEN];
85 for( int i = 0; i <= total_divisions; i++ ) {
86 int y1 = canvas_y + (int)(i * pixels_per_division);
88 int x2 = canvas_x - big_xtick;
89 int x3 = canvas_x - tiny_xtick;
90 int x4 = x3 - small_xtick;
92 if( !(i % minor_divisions) ||
93 i == total_divisions ) {
94 if( i == total_divisions ) {
95 sprintf(string, "oo");
98 sprintf(string, "%d", (int)(max_db - i * db_per_division));
101 parent->set_color(BLACK);
102 int text_w = parent->get_text_width(SMALLFONT, string, -1);
103 int x1 = canvas_x - big_xtick - text_w;
104 parent->set_color(parent->get_resources()->default_text_color);
105 parent->draw_text(x1, y2, string);
106 parent->draw_line(x2, y1, x3, y1);
109 parent->draw_line(x4, y1, x3, y1);
114 for( int i = 0; i <= freq_divisions; i++ ) {
115 int freq = Freq::tofreq(i * TOTALFREQS / freq_divisions);
116 sprintf(string, "%d", freq);
117 int x1 = canvas_x + i * canvas_w / freq_divisions;
118 int x2 = x1 - parent->get_text_width(SMALLFONT, string);
119 int y1 = canvas_y + canvas_h;
120 int y2 = y1 + big_ytick;
121 int y3 = y1 + small_ytick;
122 int y4 = y2 + parent->get_text_ascent(SMALLFONT);
124 // parent->set_color(BLACK);
125 // parent->draw_text(x2 + 1, y4 + 1, string);
126 // parent->draw_line(x1 + 1, y1 + 1, x1 + 1, y2 + 1);
127 // parent->set_color(RED);
128 parent->set_color(parent->get_resources()->default_text_color);
129 parent->draw_text(x2, y4, string);
130 parent->draw_line(x1, y1, x1, y2);
132 if( i < freq_divisions ) {
133 for( int j = 0; j < minor_divisions; j++ ) {
135 (canvas_w / freq_divisions) -
136 exp(-(double)j * 0.7) *
137 (canvas_w / freq_divisions));
138 // parent->set_color(BLACK);
139 // parent->draw_line(x3 + 1, y1 + 1, x3 + 1, y3 + 1);
140 // parent->set_color(RED);
141 parent->set_color(parent->get_resources()->default_text_color);
142 parent->draw_line(x3, y1, x3, y3);
151 void EQCanvas::draw_grid()
153 canvas->set_line_dashes(1);
154 canvas->set_color(graph_grid_color);
155 for( int i = minor_divisions; i < total_divisions; i += minor_divisions ) {
156 int y = (int)(i * pixels_per_division);
157 canvas->draw_line(0, y, canvas_w, y);
159 // for( int i = 1; i < major_divisions; i++ ) {
160 // int y = canvas_h - i * canvas_h / major_divisions;
161 // canvas->draw_line(0, y, canvas_w, y);
163 for( int i = 1; i < freq_divisions; i++ ) {
164 int x = i * canvas_w / freq_divisions;
165 canvas->draw_line(x, 0, x, canvas_h);
167 canvas->set_line_dashes(0);
170 void EQCanvas::update_spectrogram(CompressorFreqFrame *frame,
171 int offset, int size, int window_size)
173 //if( frame ) printf("EQCanvas::update_spectrogram %d frame->freq_max=%f frame->data=%p\n",
174 // __LINE__, frame->freq_max, frame->data);
175 canvas->set_color(graph_bg_color);
176 canvas->draw_box(0, 0, canvas->get_w(), canvas->get_h());
180 if( frame && !EQUIV(frame->freq_max, 0.0) && frame->data ) {
184 size = frame->data_size;
185 window_size = frame->data_size * 2;
188 canvas->set_color(graph_inactive_color);
189 if( !EQUIV(frame->freq_max, 0) ) {
190 for( int i = 0; i < canvas->get_w(); i++ ) {
191 int freq = Freq::tofreq(i * TOTALFREQS / canvas->get_w());
193 if( freq < frame->nyquist ) {
195 (int64_t)freq * (int64_t)window_size / 2 /
198 if( index < frame->data_size ) {
199 double magnitude = frame->data[index] /
200 frame->freq_max * frame->time_max;
202 y2 = (int)(canvas->get_h() -
203 (DB::todb(magnitude) - INFINITYGAIN) *
206 CLAMP(y2, 0, canvas->get_h() - 1);
208 canvas->draw_line(i - 1, y1, i, y2);
214 // printf("EQCanvas::update_spectrogram %d i=%d freq=%d nyquist=%d\n",
215 // __LINE__, i, freq, frame->nyquist);
224 void EQCanvas::draw_envelope(double *envelope,
225 int samplerate, int window_size, int is_top, int flash_it)
227 int niquist = samplerate / 2;
230 canvas->set_color(graph_active_color);
231 canvas->set_line_width(2);
234 canvas->set_color(graph_inactive_color);
235 canvas->set_line_width(1);
239 for( int i = 0; i < canvas->get_w(); i++ ) {
240 int freq = Freq::tofreq(i * TOTALFREQS / canvas->get_w());
241 int index = (int64_t)freq * (int64_t)window_size / 2 / niquist;
242 if( freq < niquist && index < window_size / 2 ) {
243 double mag = envelope[index];
244 int y2 = (int)(DB::todb(mag) * canvas->get_h() / INFINITYGAIN);
246 if( y2 >= canvas->get_h() ) {
247 y2 = canvas->get_h() - 1;
251 canvas->draw_line(i - 1, y1, i, y2);
257 int y2 = canvas->get_h() - 1;
258 canvas->draw_line(i - 1, y1, i, y2);
263 canvas->set_line_width(1);