1 #include "bcdisplayinfo.h"
7 #include "pluginaclient.h"
8 #include "revmodel.hpp"
28 int equivalent(FreeverbConfig &that);
29 void copy_from(FreeverbConfig &that);
30 void interpolate(FreeverbConfig &prev,
34 int64_t current_frame);
47 class FreeverbGain : public BC_FPot
50 FreeverbGain(FreeverbEffect *plugin, int x, int y);
52 FreeverbEffect *plugin;
55 class FreeverbRoomsize : public BC_FPot
58 FreeverbRoomsize(FreeverbEffect *plugin, int x, int y);
60 FreeverbEffect *plugin;
63 class FreeverbDamp : public BC_FPot
66 FreeverbDamp(FreeverbEffect *plugin, int x, int y);
68 FreeverbEffect *plugin;
71 class FreeverbWet : public BC_FPot
74 FreeverbWet(FreeverbEffect *plugin, int x, int y);
76 FreeverbEffect *plugin;
79 class FreeverbDry : public BC_FPot
82 FreeverbDry(FreeverbEffect *plugin, int x, int y);
84 FreeverbEffect *plugin;
87 class FreeverbWidth : public BC_FPot
90 FreeverbWidth(FreeverbEffect *plugin, int x, int y);
92 FreeverbEffect *plugin;
95 class FreeverbMode : public BC_CheckBox
98 FreeverbMode(FreeverbEffect *plugin, int x, int y);
100 FreeverbEffect *plugin;
105 class FreeverbWindow : public BC_Window
108 FreeverbWindow(FreeverbEffect *plugin, int x, int y);
109 void create_objects();
112 FreeverbEffect *plugin;
115 FreeverbRoomsize *roomsize;
119 FreeverbWidth *width;
123 PLUGIN_THREAD_HEADER(FreeverbEffect, FreeverbThread, FreeverbWindow)
127 class FreeverbEffect : public PluginAClient
130 FreeverbEffect(PluginServer *server);
134 char* plugin_title();
139 int is_multichannel();
140 void read_data(KeyFrame *keyframe);
141 void save_data(KeyFrame *keyframe);
142 int process_realtime(int64_t size, double **input_ptr, double **output_ptr);
149 int load_configuration();
154 FreeverbThread *thread;
155 FreeverbConfig config;
165 REGISTER_PLUGIN(FreeverbEffect)
176 FreeverbGain::FreeverbGain(FreeverbEffect *plugin, int x, int y)
177 : BC_FPot(x, y, plugin->config.gain, INFINITYGAIN, 6)
179 this->plugin = plugin;
183 int FreeverbGain::handle_event()
185 plugin->config.gain = get_value();
186 plugin->send_configure_change();
190 FreeverbRoomsize::FreeverbRoomsize(FreeverbEffect *plugin, int x, int y)
191 : BC_FPot(x, y, plugin->config.roomsize, INFINITYGAIN, 0)
193 this->plugin = plugin;
197 int FreeverbRoomsize::handle_event()
199 plugin->config.roomsize = get_value();
200 plugin->send_configure_change();
204 FreeverbDamp::FreeverbDamp(FreeverbEffect *plugin, int x, int y)
205 : BC_FPot(x, y, plugin->config.damp, INFINITYGAIN, 0)
207 this->plugin = plugin;
211 int FreeverbDamp::handle_event()
213 plugin->config.damp = get_value();
214 plugin->send_configure_change();
218 FreeverbWet::FreeverbWet(FreeverbEffect *plugin, int x, int y)
219 : BC_FPot(x, y, plugin->config.wet, INFINITYGAIN, 0)
221 this->plugin = plugin;
225 int FreeverbWet::handle_event()
227 plugin->config.wet = get_value();
228 plugin->send_configure_change();
232 FreeverbDry::FreeverbDry(FreeverbEffect *plugin, int x, int y)
233 : BC_FPot(x, y, plugin->config.dry, INFINITYGAIN, 0)
235 this->plugin = plugin;
239 int FreeverbDry::handle_event()
241 plugin->config.dry = get_value();
242 plugin->send_configure_change();
246 FreeverbWidth::FreeverbWidth(FreeverbEffect *plugin, int x, int y)
247 : BC_FPot(x, y, plugin->config.width, INFINITYGAIN, 0)
249 this->plugin = plugin;
253 int FreeverbWidth::handle_event()
255 plugin->config.width = get_value();
256 plugin->send_configure_change();
260 FreeverbMode::FreeverbMode(FreeverbEffect *plugin, int x, int y)
261 : BC_CheckBox(x, y, (int)plugin->config.mode, "Freeze")
263 this->plugin = plugin;
266 int FreeverbMode::handle_event()
268 plugin->config.mode = get_value();
269 plugin->send_configure_change();
283 FreeverbWindow::FreeverbWindow(FreeverbEffect *plugin, int x, int y)
284 : BC_Window(plugin->gui_string,
295 this->plugin = plugin;
298 void FreeverbWindow::create_objects()
300 int x1 = 10, x2 = 100, x3 = 135, y1 = 10, y2 = 20, margin = 30;
302 add_subwindow(new BC_Title(x1, y2, "Gain:"));
303 add_subwindow(gain = new FreeverbGain(plugin, x3, y1));
306 add_subwindow(new BC_Title(x1, y2, "Roomsize:"));
307 add_subwindow(roomsize = new FreeverbRoomsize(plugin, x2, y1));
310 add_subwindow(new BC_Title(x1, y2, "Damp:"));
311 add_subwindow(damp = new FreeverbDamp(plugin, x3, y1));
314 add_subwindow(new BC_Title(x1, y2, "Wet:"));
315 add_subwindow(wet = new FreeverbWet(plugin, x2, y1));
318 add_subwindow(new BC_Title(x1, y2, "Dry:"));
319 add_subwindow(dry = new FreeverbDry(plugin, x3, y1));
322 add_subwindow(new BC_Title(x1, y2, "Width:"));
323 add_subwindow(width = new FreeverbWidth(plugin, x2, y1));
326 add_subwindow(mode = new FreeverbMode(plugin, x1, y2));
331 int FreeverbWindow::close_event()
333 // Set result to 1 to indicate a client side close
349 FreeverbConfig::FreeverbConfig()
360 int FreeverbConfig::equivalent(FreeverbConfig &that)
362 return EQUIV(gain, that.gain) &&
363 EQUIV(wet, that.wet) &&
364 EQUIV(roomsize, that.roomsize) &&
365 EQUIV(dry, that.dry) &&
366 EQUIV(damp, that.damp) &&
367 EQUIV(width, that.width) &&
368 EQUIV(mode, that.mode);
371 void FreeverbConfig::copy_from(FreeverbConfig &that)
375 roomsize = that.roomsize;
382 void FreeverbConfig::interpolate(FreeverbConfig &prev,
383 FreeverbConfig &next,
386 int64_t current_frame)
388 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
389 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
391 gain = prev.gain * prev_scale + next.gain * next_scale;
392 wet = prev.wet * prev_scale + next.wet * next_scale;
393 roomsize = prev.roomsize * prev_scale + next.roomsize * next_scale;
394 dry = prev.dry * prev_scale + next.dry * next_scale;
395 damp = prev.damp * prev_scale + next.damp * next_scale;
396 width = prev.width * prev_scale + next.width * next_scale;
423 PLUGIN_THREAD_OBJECT(FreeverbEffect, FreeverbThread, FreeverbWindow)
429 FreeverbEffect::FreeverbEffect(PluginServer *server)
430 : PluginAClient(server)
436 PLUGIN_CONSTRUCTOR_MACRO
439 FreeverbEffect::~FreeverbEffect()
441 if(engine) delete engine;
444 for(int i = 0; i < total_in_buffers; i++)
447 delete [] temp_out[i];
452 PLUGIN_DESTRUCTOR_MACRO
455 NEW_PICON_MACRO(FreeverbEffect)
457 LOAD_CONFIGURATION_MACRO(FreeverbEffect, FreeverbConfig)
459 SHOW_GUI_MACRO(FreeverbEffect, FreeverbThread)
461 RAISE_WINDOW_MACRO(FreeverbEffect)
463 SET_STRING_MACRO(FreeverbEffect)
466 char* FreeverbEffect::plugin_title()
472 int FreeverbEffect::is_realtime()
477 int FreeverbEffect::is_multichannel()
484 void FreeverbEffect::read_data(KeyFrame *keyframe)
487 input.set_shared_string(keyframe->data, strlen(keyframe->data));
492 result = input.read_tag();
496 if(input.tag.title_is("FREEVERB"))
498 config.gain = input.tag.get_property("GAIN", config.gain);
499 config.roomsize = input.tag.get_property("ROOMSIZE", config.roomsize);
500 config.damp = input.tag.get_property("DAMP", config.damp);
501 config.wet = input.tag.get_property("WET", config.wet);
502 config.dry = input.tag.get_property("DRY", config.dry);
503 config.width = input.tag.get_property("WIDTH", config.width);
504 config.mode = input.tag.get_property("MODE", config.mode);
510 void FreeverbEffect::save_data(KeyFrame *keyframe)
513 output.set_shared_string(keyframe->data, MESSAGESIZE);
515 output.tag.set_title("FREEVERB");
516 output.tag.set_property("GAIN", config.gain);
517 output.tag.set_property("ROOMSIZE", config.roomsize);
518 output.tag.set_property("DAMP", config.damp);
519 output.tag.set_property("WET", config.wet);
520 output.tag.set_property("DRY", config.dry);
521 output.tag.set_property("WIDTH", config.width);
522 output.tag.set_property("MODE", config.mode);
524 output.append_newline();
526 output.terminate_string();
529 int FreeverbEffect::load_defaults()
531 char directory[BCTEXTLEN], string[BCTEXTLEN];
532 sprintf(directory, "%sfreeverb.rc", BCASTDIR);
533 defaults = new Defaults(directory);
536 config.gain = defaults->get("GAIN", config.gain);
537 config.roomsize = defaults->get("ROOMSIZE", config.roomsize);
538 config.damp = defaults->get("DAMP", config.damp);
539 config.wet = defaults->get("WET", config.wet);
540 config.dry = defaults->get("DRY", config.dry);
541 config.width = defaults->get("WIDTH", config.width);
542 config.mode = defaults->get("MODE", config.mode);
546 int FreeverbEffect::save_defaults()
548 char string[BCTEXTLEN];
550 defaults->update("GAIN", config.gain);
551 defaults->update("ROOMSIZE", config.roomsize);
552 defaults->update("DAMP", config.damp);
553 defaults->update("WET", config.wet);
554 defaults->update("DRY", config.dry);
555 defaults->update("WIDTH", config.width);
556 defaults->update("MODE", config.mode);
563 void FreeverbEffect::update_gui()
567 load_configuration();
568 thread->window->lock_window();
569 thread->window->gain->update(config.gain);
570 thread->window->roomsize->update(config.roomsize);
571 thread->window->damp->update(config.damp);
572 thread->window->wet->update(config.wet);
573 thread->window->dry->update(config.dry);
574 thread->window->width->update(config.width);
575 thread->window->mode->update((int)config.mode);
576 thread->window->unlock_window();
580 int FreeverbEffect::process_realtime(int64_t size, double **input_ptr, double **output_ptr)
582 load_configuration();
583 if(!engine) engine = new revmodel;
585 engine->setroomsize(DB::fromdb(config.roomsize));
586 engine->setdamp(DB::fromdb(config.damp));
587 engine->setwet(DB::fromdb(config.wet));
588 engine->setdry(DB::fromdb(config.dry));
589 engine->setwidth(DB::fromdb(config.width));
590 engine->setmode(config.mode);
592 float gain_f = DB::fromdb(config.gain);
594 if(size > temp_allocated)
598 for(int i = 0; i < total_in_buffers; i++)
601 delete [] temp_out[i];
611 temp_allocated = size * 2;
612 temp = new float*[total_in_buffers];
613 temp_out = new float*[total_in_buffers];
614 for(int i = 0; i < total_in_buffers; i++)
616 temp[i] = new float[temp_allocated];
617 temp_out[i] = new float[temp_allocated];
621 for(int i = 0; i < 2 && i < total_in_buffers; i++)
623 float *out = temp[i];
624 double *in = input_ptr[i];
625 for(int j = 0; j < size; j++)
631 if(total_in_buffers < 2)
633 engine->processreplace(temp[0],
642 engine->processreplace(temp[0],
650 for(int i = 0; i < 2 && i < total_in_buffers; i++)
652 double *out = output_ptr[i];
653 float *in = temp_out[i];
654 for(int j = 0; j < size; j++)
656 out[j] = gain_f * in[j];