1 #include "bcdisplayinfo.h"
5 #include "spectrogram.h"
13 #define _(String) gettext(String)
14 #define gettext_noop(String) String
15 #define N_(String) gettext_noop (String)
19 REGISTER_PLUGIN(Spectrogram)
25 SpectrogramConfig::SpectrogramConfig()
36 SpectrogramLevel::SpectrogramLevel(Spectrogram *plugin, int x, int y)
37 : BC_FPot(x, y, plugin->config.level, INFINITYGAIN, 0)
39 this->plugin = plugin;
42 int SpectrogramLevel::handle_event()
44 plugin->config.level = get_value();
45 plugin->send_configure_change();
59 SpectrogramWindow::SpectrogramWindow(Spectrogram *plugin, int x, int y)
60 : BC_Window(plugin->gui_string,
71 this->plugin = plugin;
74 SpectrogramWindow::~SpectrogramWindow()
78 void SpectrogramWindow::create_objects()
82 char string[BCTEXTLEN];
84 add_subwindow(canvas = new BC_SubWindow(x,
91 for(int i = 0; i <= divisions; i++)
93 y = (int)((float)(canvas->get_h() - 10) / divisions * i) + 10;
95 Freq::tofreq((int)((float)TOTALFREQS / divisions * (divisions - i))));
96 add_subwindow(new BC_Title(x, y, string));
100 y = canvas->get_y() + canvas->get_h() + 5;
102 add_subwindow(new BC_Title(x, y + 10, _("Level:")));
103 add_subwindow(level = new SpectrogramLevel(plugin, x + 50, y));
109 WINDOW_CLOSE_EVENT(SpectrogramWindow)
112 void SpectrogramWindow::update_gui()
114 level->update(plugin->config.level);
126 PLUGIN_THREAD_OBJECT(Spectrogram, SpectrogramThread, SpectrogramWindow)
136 SpectrogramFFT::SpectrogramFFT(Spectrogram *plugin)
139 this->plugin = plugin;
142 SpectrogramFFT::~SpectrogramFFT()
147 int SpectrogramFFT::signal_process()
150 //printf("SpectrogramFFT::signal_process %d\n", window_size);
151 BC_SubWindow *window = plugin->thread->window->canvas;
153 int h = window->get_h();
154 double *temp = new double[h];
155 int niquist = plugin->PluginAClient::project_sample_rate / 2;
156 int input1 = window_size / 2;
157 double level = DB::fromdb(plugin->config.level);
159 for(int i = 0; i < h; i++)
161 int input2 = (int)((float)(h - 1 - i) / h * TOTALFREQS);
162 input2 = (int)((float)Freq::tofreq(input2) /
166 if(input2 > window_size / 2 - 1) input2 = window_size / 2 - 1;
171 for(int j = input1 - 1; j >= input2; j--)
172 sum += sqrt(freq_real[j] * freq_real[j] +
173 freq_imag[j] * freq_imag[j]);
175 sum /= (double)(input1 - input2);
178 sum = sqrt(freq_real[input2] * freq_real[input2] +
179 freq_imag[input2] * freq_imag[input2]);
182 temp[i] = sum * level;
192 int x = window->get_w() - 1;
194 double scale = (double)0xffffff;
195 for(int i = 0; i < h; i++)
198 color = (int)(scale * temp[i]);
200 if(color < 0) color = 0;
201 if(color > 0xffffff) color = 0xffffff;
202 window->set_color(color);
203 window->draw_pixel(x, i);
222 Spectrogram::Spectrogram(PluginServer *server)
223 : PluginAClient(server)
226 PLUGIN_CONSTRUCTOR_MACRO
229 Spectrogram::~Spectrogram()
231 PLUGIN_DESTRUCTOR_MACRO
237 void Spectrogram::reset()
245 char* Spectrogram::plugin_title()
247 return _("Spectrogram");
250 int Spectrogram::is_realtime()
255 int Spectrogram::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
257 //printf("Spectrogram::process_realtime 1\n");
258 send_render_gui(input_ptr, size);
259 memcpy(output_ptr, input_ptr, sizeof(double) * size);
264 SET_STRING_MACRO(Spectrogram)
266 NEW_PICON_MACRO(Spectrogram)
268 SHOW_GUI_MACRO(Spectrogram, SpectrogramThread)
270 RAISE_WINDOW_MACRO(Spectrogram)
272 void Spectrogram::update_gui()
276 load_configuration();
277 thread->window->lock_window();
278 thread->window->update_gui();
279 thread->window->unlock_window();
283 void Spectrogram::render_gui(void *data, int size)
285 //printf("Spectrogram::render_gui 1\n");
288 thread->window->lock_window();
289 load_configuration();
293 fft = new SpectrogramFFT(this);
294 fft->initialize(WINDOW_SIZE);
296 double *temp = new double[size];
297 fft->process_fifo(size, (double*)data, temp);
300 thread->window->unlock_window();
304 void Spectrogram::load_configuration()
306 KeyFrame *prev_keyframe;
307 prev_keyframe = get_prev_keyframe(get_source_position());
309 read_data(prev_keyframe);
312 void Spectrogram::read_data(KeyFrame *keyframe)
315 input.set_shared_string(keyframe->data, strlen(keyframe->data));
320 result = input.read_tag();
324 if(input.tag.title_is("SPECTROGRAM"))
326 config.level = input.tag.get_property("LEVEL", config.level);
332 void Spectrogram::save_data(KeyFrame *keyframe)
335 output.set_shared_string(keyframe->data, MESSAGESIZE);
337 output.tag.set_title("SPECTROGRAM");
338 output.tag.set_property("LEVEL", (double)config.level);
340 output.append_newline();
341 output.terminate_string();
344 int Spectrogram::load_defaults()
346 char directory[BCTEXTLEN];
348 sprintf(directory, "%sspectrogram.rc", BCASTDIR);
349 defaults = new Defaults(directory);
351 config.level = defaults->get("LEVEL", config.level);
355 int Spectrogram::save_defaults()
357 defaults->update("LEVEL", config.level);