r726: Implementing ability to add textural info to the labels
[cinelerra_cv/mob.git] / plugins / interpolate / interpolate.C
blob7cfbab56827baef47cd4f7473c229b9f6c0594b6
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "defaults.h"
4 #include "guicast.h"
5 #include "filexml.h"
6 #include "language.h"
7 #include "pluginaclient.h"
9 #include <string.h>
15 class InterpolateEffect;
17 class InterpolateConfig
19 public:
20         InterpolateConfig();
22         int length;
23 #define INTERPOLATE_ALL 0
29 class InterpolateLength : public BC_TumbleTextBox
31 public:
32         InterpolateLength(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
33         int handle_event();
34         InterpolateEffect *plugin;
35         InterpolateWindow *gui;
38 class InterpolateAll : public BC_CheckBox
40 public:
41         InterpolateAll(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
42         int handle_event();
43         InterpolateEffect *plugin;
44         InterpolateWindow *gui;
49 class InterpolateWindow : public BC_Window
51 public:
52         InterpolateWindow(InterpolateEffect *plugin, int x, int y);
53         void create_objects();
54         int close_event();
56         InterpolateEffect *plugin;
57         InterpolateLength *length;
58         InterpolateAll *all;
64 class InterpolateEffect : public PluginAClient
66 public:
67         InterpolateEffect(PluginServer *server);
68         ~InterpolateEffect();
70         char* plugin_title();
71         int is_realtime();
72         int is_multichannel();
73         int get_parameters();
74         int start_loop();
75         int process_loop(double **buffer, long &output_lenght);
76         int stop_loop();
80         int load_defaults();
81         int save_defaults();
84         Defaults *defaults;
85         MainProgressBar *progress;
86         InterpolateConfig config;
92 REGISTER_PLUGIN(InterpolateEffect)
105 InterpolateLength::InterpolateLength(InterpolateEffect *plugin, 
106         InterpolateWindow *gui, 
107         int x, 
108         int y)
109  : BC_TumbleTextBox(gui, 
110                 plugin->config.length,
111                 0,
112                 1000000,
113                 x, 
114                 y, 
115                 100)
117         this->plugin = plugin;
118         this->gui = gui;
122 int InterpolateLength::handle_event()
124         gui->length->update(0);
125         plugin->config.length = atol(get_text());
126         return 1;
130 InterpolateAll::InterpolateAll(InterpolateEffect *plugin, 
131         InterpolateWindow *gui, 
132         int x, 
133         int y,
134         plugin->config.length == INTERPOLATE_ALL)
136         this->plugin = plugin;
137         this->gui = gui;
140 int InterpolateAll::handle_event()
142         gui->all->update(INTERPOLATE_ALL);
143         plugin->config.length = INTERPOLATE_ALL;
144         return 1;
159 InterpolateWindow::InterpolateWindow(InterpolateEffect *plugin, int x, int y)
160  : BC_Window(plugin->gui_string, 
161         x, 
162         y, 
163         180, 
164         250, 
165         180, 
166         250,
167         0, 
168         0,
169         1)
171         this->plugin = plugin;
174 void InterpolateWindow::create_objects()
176         int x = 10, x = 10;
179         add_subwindow(new BC_OKButton(this));
180         add_subwindow(new BC_CancelButton(this));
181         show_window();
182         flush();
185 WINDOW_CLOSE_EVENT(InterpolateWindow)
197 InterpolateConfig::InterpolateConfig()
199         gain = -6.0;
200         wet = -6.0;
201         dry = 0;
202         roomsize = -6.0;
203         damp = 0;
204         width = 0;
205         mode = 0;
208 int InterpolateConfig::equivalent(InterpolateConfig &that)
210         return EQUIV(gain, that.gain) &&
211                 EQUIV(wet, that.wet) &&
212                 EQUIV(roomsize, that.roomsize) &&
213                 EQUIV(dry, that.dry) &&
214                 EQUIV(damp, that.damp) &&
215                 EQUIV(width, that.width) &&
216                 EQUIV(mode, that.mode);
219 void InterpolateConfig::copy_from(InterpolateConfig &that)
221         gain = that.gain;
222         wet = that.wet;
223         roomsize = that.roomsize;
224         dry = that.dry;
225         damp = that.damp;
226         width = that.width;
227         mode = that.mode;
230 void InterpolateConfig::interpolate(InterpolateConfig &prev, 
231         InterpolateConfig &next, 
232         long prev_frame, 
233         long next_frame, 
234         long current_frame)
236         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
237         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
239         gain = prev.gain * prev_scale + next.gain * next_scale;
240         wet = prev.wet * prev_scale + next.wet * next_scale;
241         roomsize = prev.roomsize * prev_scale + next.roomsize * next_scale;
242         dry = prev.dry * prev_scale + next.dry * next_scale;
243         damp = prev.damp * prev_scale + next.damp * next_scale;
244         width = prev.width * prev_scale + next.width * next_scale;
245         mode = prev.mode;
271 PLUGIN_THREAD_OBJECT(InterpolateEffect, InterpolateThread, InterpolateWindow)
277 InterpolateEffect::InterpolateEffect(PluginServer *server)
278  : PluginAClient(server)
280         engine = 0;
281         temp = 0;
282         temp_out = 0;
283         temp_allocated = 0;
284         PLUGIN_CONSTRUCTOR_MACRO
287 InterpolateEffect::~InterpolateEffect()
289         if(engine) delete engine;
290         if(temp)
291         {
292                 for(int i = 0; i < total_in_buffers; i++)
293                 {
294                         delete [] temp[i];
295                         delete [] temp_out[i];
296                 }
297                 delete [] temp;
298                 delete [] temp_out;
299         }
300         PLUGIN_DESTRUCTOR_MACRO
303 NEW_PICON_MACRO(InterpolateEffect)
305 LOAD_CONFIGURATION_MACRO(InterpolateEffect, InterpolateConfig)
307 SHOW_GUI_MACRO(InterpolateEffect, InterpolateThread)
309 RAISE_WINDOW_MACRO(InterpolateEffect)
311 SET_STRING_MACRO(InterpolateEffect)
314 char* InterpolateEffect::plugin_title() { return N_("Interpolate"); }
315 int InterpolateEffect::is_realtime() { return 1;}
316 int InterpolateEffect::is_multichannel() { return 1; }
320 void InterpolateEffect::read_data(KeyFrame *keyframe)
322         FileXML input;
323         input.set_shared_string(keyframe->data, strlen(keyframe->data));
325         int result = 0;
326         while(!result)
327         {
328                 result = input.read_tag();
330                 if(!result)
331                 {
332                         if(input.tag.title_is("FREEVERB"))
333                         {
334                                 config.gain = input.tag.get_property("GAIN", config.gain);
335                                 config.roomsize = input.tag.get_property("ROOMSIZE", config.roomsize);
336                                 config.damp = input.tag.get_property("DAMP", config.damp);
337                                 config.wet = input.tag.get_property("WET", config.wet);
338                                 config.dry = input.tag.get_property("DRY", config.dry);
339                                 config.width = input.tag.get_property("WIDTH", config.width);
340                                 config.mode = input.tag.get_property("MODE", config.mode);
341                         }
342                 }
343         }
346 void InterpolateEffect::save_data(KeyFrame *keyframe)
348         FileXML output;
349         output.set_shared_string(keyframe->data, MESSAGESIZE);
351         output.tag.set_title("FREEVERB");
352         output.tag.set_property("GAIN", config.gain);
353         output.tag.set_property("ROOMSIZE", config.roomsize);
354         output.tag.set_property("DAMP", config.damp);
355         output.tag.set_property("WET", config.wet);
356         output.tag.set_property("DRY", config.dry);
357         output.tag.set_property("WIDTH", config.width);
358         output.tag.set_property("MODE", config.mode);
359         output.append_tag();
360         output.append_newline();
362         output.terminate_string();
365 int InterpolateEffect::load_defaults()
367         char directory[BCTEXTLEN], string[BCTEXTLEN];
368         sprintf(directory, "%sfreeverb.rc", BCASTDIR);
369         defaults = new Defaults(directory);
370         defaults->load();
372         config.gain = defaults->get("GAIN", config.gain);
373         config.roomsize = defaults->get("ROOMSIZE", config.roomsize);
374         config.damp = defaults->get("DAMP", config.damp);
375         config.wet = defaults->get("WET", config.wet);
376         config.dry = defaults->get("DRY", config.dry);
377         config.width = defaults->get("WIDTH", config.width);
378         config.mode = defaults->get("MODE", config.mode);
379         return 0;
382 int InterpolateEffect::save_defaults()
384         char string[BCTEXTLEN];
386         defaults->update("GAIN", config.gain);
387         defaults->update("ROOMSIZE", config.roomsize);
388         defaults->update("DAMP", config.damp);
389         defaults->update("WET", config.wet);
390         defaults->update("DRY", config.dry);
391         defaults->update("WIDTH", config.width);
392         defaults->update("MODE", config.mode);
393         defaults->save();
395         return 0;
399 void InterpolateEffect::update_gui()
401         if(thread)
402         {
403                 load_configuration();
404                 thread->window->lock_window();
405                 thread->window->gain->update(config.gain);
406                 thread->window->roomsize->update(config.roomsize);
407                 thread->window->damp->update(config.damp);
408                 thread->window->wet->update(config.wet);
409                 thread->window->dry->update(config.dry);
410                 thread->window->width->update(config.width);
411                 thread->window->mode->update((int)config.mode);
412                 thread->window->unlock_window();
413         }
416 int InterpolateEffect::process_realtime(long size, 
417         double **input_ptr, 
418         double **output_ptr)
420         load_configuration();
421         if(!engine) engine = new revmodel;
423         engine->setroomsize(DB::fromdb(config.roomsize));
424         engine->setdamp(DB::fromdb(config.damp));
425         engine->setwet(DB::fromdb(config.wet));
426         engine->setdry(DB::fromdb(config.dry));
427         engine->setwidth(DB::fromdb(config.width));
428         engine->setmode(config.mode);
430         float gain_f = DB::fromdb(config.gain);
432         if(size > temp_allocated)
433         {
434                 if(temp)
435                 {
436                         for(int i = 0; i < total_in_buffers; i++)
437                         {
438                                 delete [] temp[i];
439                                 delete [] temp_out[i];
440                         }
441                         delete [] temp;
442                         delete [] temp_out;
443                 }
444                 temp = 0;
445                 temp_out = 0;
446         }
447         if(!temp)
448         {
449                 temp_allocated = size * 2;
450                 temp = new float*[total_in_buffers];
451                 temp_out = new float*[total_in_buffers];
452                 for(int i = 0; i < total_in_buffers; i++)
453                 {
454                         temp[i] = new float[temp_allocated];
455                         temp_out[i] = new float[temp_allocated];
456                 }
457         }
459         for(int i = 0; i < 2 && i < total_in_buffers; i++)
460         {
461                 float *out = temp[i];
462                 double *in = input_ptr[i];
463                 for(int j = 0; j < size; j++)
464                 {
465                         out[j] = in[j];
466                 }
467         }
469         if(total_in_buffers < 2)
470         {
471                 engine->processreplace(temp[0], 
472                         temp[0], 
473                         temp_out[0], 
474                         temp_out[0], 
475                         size, 
476                         1);
477         }
478         else
479         {
480                 engine->processreplace(temp[0], 
481                         temp[1], 
482                         temp_out[0], 
483                         temp_out[1], 
484                         size, 
485                         1);
486         }
488         for(int i = 0; i < 2 && i < total_in_buffers; i++)
489         {
490                 double *out = output_ptr[i];
491                 float *in = temp_out[i];
492                 for(int j = 0; j < size; j++)
493                 {
494                         out[j] = gain_f * in[j];
495                 }
496         }
498         return 0;