1 #include "bcdisplayinfo.h"
6 #include "pluginaclient.h"
7 #include "interpolate.h"
15 class InterpolateEffect;
17 class InterpolateConfig
23 #define INTERPOLATE_ALL 0
29 class InterpolateLength : public BC_TumbleTextBox
32 InterpolateLength(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
34 InterpolateEffect *plugin;
35 InterpolateWindow *gui;
38 class InterpolateAll : public BC_CheckBox
41 InterpolateAll(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
43 InterpolateEffect *plugin;
44 InterpolateWindow *gui;
49 class InterpolateWindow : public BC_Window
52 InterpolateWindow(InterpolateEffect *plugin, int x, int y);
53 void create_objects();
56 InterpolateEffect *plugin;
57 InterpolateLength *length;
64 class InterpolateEffect : public PluginAClient
67 InterpolateEffect(PluginServer *server);
72 int is_multichannel();
75 int process_loop(double **buffer, long &output_lenght);
85 MainProgressBar *progress;
86 InterpolateConfig config;
92 REGISTER_PLUGIN(InterpolateEffect)
105 InterpolateLength::InterpolateLength(InterpolateEffect *plugin,
106 InterpolateWindow *gui,
109 : BC_TumbleTextBox(gui,
110 plugin->config.length,
117 this->plugin = plugin;
122 int InterpolateLength::handle_event()
124 gui->length->update(0);
125 plugin->config.length = atol(get_text());
130 InterpolateAll::InterpolateAll(InterpolateEffect *plugin,
131 InterpolateWindow *gui,
134 plugin->config.length == INTERPOLATE_ALL)
136 this->plugin = plugin;
140 int InterpolateAll::handle_event()
142 gui->all->update(INTERPOLATE_ALL);
143 plugin->config.length = INTERPOLATE_ALL;
159 InterpolateWindow::InterpolateWindow(InterpolateEffect *plugin, int x, int y)
160 : BC_Window(plugin->gui_string,
171 this->plugin = plugin;
174 void InterpolateWindow::create_objects()
179 add_subwindow(new BC_OKButton(this));
180 add_subwindow(new BC_CancelButton(this));
184 WINDOW_CLOSE_EVENT(InterpolateWindow)
196 InterpolateConfig::InterpolateConfig()
207 int InterpolateConfig::equivalent(InterpolateConfig &that)
209 return EQUIV(gain, that.gain) &&
210 EQUIV(wet, that.wet) &&
211 EQUIV(roomsize, that.roomsize) &&
212 EQUIV(dry, that.dry) &&
213 EQUIV(damp, that.damp) &&
214 EQUIV(width, that.width) &&
215 EQUIV(mode, that.mode);
218 void InterpolateConfig::copy_from(InterpolateConfig &that)
222 roomsize = that.roomsize;
229 void InterpolateConfig::interpolate(InterpolateConfig &prev,
230 InterpolateConfig &next,
235 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
236 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
238 gain = prev.gain * prev_scale + next.gain * next_scale;
239 wet = prev.wet * prev_scale + next.wet * next_scale;
240 roomsize = prev.roomsize * prev_scale + next.roomsize * next_scale;
241 dry = prev.dry * prev_scale + next.dry * next_scale;
242 damp = prev.damp * prev_scale + next.damp * next_scale;
243 width = prev.width * prev_scale + next.width * next_scale;
270 PLUGIN_THREAD_OBJECT(InterpolateEffect, InterpolateThread, InterpolateWindow)
276 InterpolateEffect::InterpolateEffect(PluginServer *server)
277 : PluginAClient(server)
283 PLUGIN_CONSTRUCTOR_MACRO
286 InterpolateEffect::~InterpolateEffect()
288 if(engine) delete engine;
291 for(int i = 0; i < total_in_buffers; i++)
294 delete [] temp_out[i];
299 PLUGIN_DESTRUCTOR_MACRO
302 NEW_PICON_MACRO(InterpolateEffect)
304 LOAD_CONFIGURATION_MACRO(InterpolateEffect, InterpolateConfig)
306 SHOW_GUI_MACRO(InterpolateEffect, InterpolateThread)
308 RAISE_WINDOW_MACRO(InterpolateEffect)
310 SET_STRING_MACRO(InterpolateEffect)
313 char* InterpolateEffect::plugin_title() { return N_("Interpolate"); }
314 int InterpolateEffect::is_realtime() { return 1;}
315 int InterpolateEffect::is_multichannel() { return 1; }
319 void InterpolateEffect::read_data(KeyFrame *keyframe)
322 input.set_shared_string(keyframe->data, strlen(keyframe->data));
327 result = input.read_tag();
331 if(input.tag.title_is("FREEVERB"))
333 config.gain = input.tag.get_property("GAIN", config.gain);
334 config.roomsize = input.tag.get_property("ROOMSIZE", config.roomsize);
335 config.damp = input.tag.get_property("DAMP", config.damp);
336 config.wet = input.tag.get_property("WET", config.wet);
337 config.dry = input.tag.get_property("DRY", config.dry);
338 config.width = input.tag.get_property("WIDTH", config.width);
339 config.mode = input.tag.get_property("MODE", config.mode);
345 void InterpolateEffect::save_data(KeyFrame *keyframe)
348 output.set_shared_string(keyframe->data, MESSAGESIZE);
350 output.tag.set_title("FREEVERB");
351 output.tag.set_property("GAIN", config.gain);
352 output.tag.set_property("ROOMSIZE", config.roomsize);
353 output.tag.set_property("DAMP", config.damp);
354 output.tag.set_property("WET", config.wet);
355 output.tag.set_property("DRY", config.dry);
356 output.tag.set_property("WIDTH", config.width);
357 output.tag.set_property("MODE", config.mode);
359 output.append_newline();
361 output.terminate_string();
364 int InterpolateEffect::load_defaults()
366 char directory[BCTEXTLEN], string[BCTEXTLEN];
367 sprintf(directory, "%sfreeverb.rc", BCASTDIR);
368 defaults = new BC_Hash(directory);
371 config.gain = defaults->get("GAIN", config.gain);
372 config.roomsize = defaults->get("ROOMSIZE", config.roomsize);
373 config.damp = defaults->get("DAMP", config.damp);
374 config.wet = defaults->get("WET", config.wet);
375 config.dry = defaults->get("DRY", config.dry);
376 config.width = defaults->get("WIDTH", config.width);
377 config.mode = defaults->get("MODE", config.mode);
381 int InterpolateEffect::save_defaults()
383 char string[BCTEXTLEN];
385 defaults->update("GAIN", config.gain);
386 defaults->update("ROOMSIZE", config.roomsize);
387 defaults->update("DAMP", config.damp);
388 defaults->update("WET", config.wet);
389 defaults->update("DRY", config.dry);
390 defaults->update("WIDTH", config.width);
391 defaults->update("MODE", config.mode);
398 void InterpolateEffect::update_gui()
402 load_configuration();
403 thread->window->lock_window();
404 thread->window->gain->update(config.gain);
405 thread->window->roomsize->update(config.roomsize);
406 thread->window->damp->update(config.damp);
407 thread->window->wet->update(config.wet);
408 thread->window->dry->update(config.dry);
409 thread->window->width->update(config.width);
410 thread->window->mode->update((int)config.mode);
411 thread->window->unlock_window();
415 int InterpolateEffect::process_realtime(long size,
419 load_configuration();
420 if(!engine) engine = new revmodel;
422 engine->setroomsize(DB::fromdb(config.roomsize));
423 engine->setdamp(DB::fromdb(config.damp));
424 engine->setwet(DB::fromdb(config.wet));
425 engine->setdry(DB::fromdb(config.dry));
426 engine->setwidth(DB::fromdb(config.width));
427 engine->setmode(config.mode);
429 float gain_f = DB::fromdb(config.gain);
431 if(size > temp_allocated)
435 for(int i = 0; i < total_in_buffers; i++)
438 delete [] temp_out[i];
448 temp_allocated = size * 2;
449 temp = new float*[total_in_buffers];
450 temp_out = new float*[total_in_buffers];
451 for(int i = 0; i < total_in_buffers; i++)
453 temp[i] = new float[temp_allocated];
454 temp_out[i] = new float[temp_allocated];
458 for(int i = 0; i < 2 && i < total_in_buffers; i++)
460 float *out = temp[i];
461 double *in = input_ptr[i];
462 for(int j = 0; j < size; j++)
468 if(total_in_buffers < 2)
470 engine->processreplace(temp[0],
479 engine->processreplace(temp[0],
487 for(int i = 0; i < 2 && i < total_in_buffers; i++)
489 double *out = output_ptr[i];
490 float *in = temp_out[i];
491 for(int j = 0; j < size; j++)
493 out[j] = gain_f * in[j];