r860: Merge 2.1:
[cinelerra_cv.git] / plugins / interpolate / interpolate.C
blobada9a9f8c8543a19d2c01952a4a4175de75882be
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "guicast.h"
4 #include "filexml.h"
5 #include "language.h"
6 #include "pluginaclient.h"
7 #include "interpolate.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         BC_Hash *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();
184 WINDOW_CLOSE_EVENT(InterpolateWindow)
196 InterpolateConfig::InterpolateConfig()
198         gain = -6.0;
199         wet = -6.0;
200         dry = 0;
201         roomsize = -6.0;
202         damp = 0;
203         width = 0;
204         mode = 0;
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)
220         gain = that.gain;
221         wet = that.wet;
222         roomsize = that.roomsize;
223         dry = that.dry;
224         damp = that.damp;
225         width = that.width;
226         mode = that.mode;
229 void InterpolateConfig::interpolate(InterpolateConfig &prev, 
230         InterpolateConfig &next, 
231         long prev_frame, 
232         long next_frame, 
233         long current_frame)
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;
244         mode = prev.mode;
270 PLUGIN_THREAD_OBJECT(InterpolateEffect, InterpolateThread, InterpolateWindow)
276 InterpolateEffect::InterpolateEffect(PluginServer *server)
277  : PluginAClient(server)
279         engine = 0;
280         temp = 0;
281         temp_out = 0;
282         temp_allocated = 0;
283         PLUGIN_CONSTRUCTOR_MACRO
286 InterpolateEffect::~InterpolateEffect()
288         if(engine) delete engine;
289         if(temp)
290         {
291                 for(int i = 0; i < total_in_buffers; i++)
292                 {
293                         delete [] temp[i];
294                         delete [] temp_out[i];
295                 }
296                 delete [] temp;
297                 delete [] temp_out;
298         }
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)
321         FileXML input;
322         input.set_shared_string(keyframe->data, strlen(keyframe->data));
324         int result = 0;
325         while(!result)
326         {
327                 result = input.read_tag();
329                 if(!result)
330                 {
331                         if(input.tag.title_is("FREEVERB"))
332                         {
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);
340                         }
341                 }
342         }
345 void InterpolateEffect::save_data(KeyFrame *keyframe)
347         FileXML output;
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);
358         output.append_tag();
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);
369         defaults->load();
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);
378         return 0;
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);
392         defaults->save();
394         return 0;
398 void InterpolateEffect::update_gui()
400         if(thread)
401         {
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();
412         }
415 int InterpolateEffect::process_realtime(long size, 
416         double **input_ptr, 
417         double **output_ptr)
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)
432         {
433                 if(temp)
434                 {
435                         for(int i = 0; i < total_in_buffers; i++)
436                         {
437                                 delete [] temp[i];
438                                 delete [] temp_out[i];
439                         }
440                         delete [] temp;
441                         delete [] temp_out;
442                 }
443                 temp = 0;
444                 temp_out = 0;
445         }
446         if(!temp)
447         {
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++)
452                 {
453                         temp[i] = new float[temp_allocated];
454                         temp_out[i] = new float[temp_allocated];
455                 }
456         }
458         for(int i = 0; i < 2 && i < total_in_buffers; i++)
459         {
460                 float *out = temp[i];
461                 double *in = input_ptr[i];
462                 for(int j = 0; j < size; j++)
463                 {
464                         out[j] = in[j];
465                 }
466         }
468         if(total_in_buffers < 2)
469         {
470                 engine->processreplace(temp[0], 
471                         temp[0], 
472                         temp_out[0], 
473                         temp_out[0], 
474                         size, 
475                         1);
476         }
477         else
478         {
479                 engine->processreplace(temp[0], 
480                         temp[1], 
481                         temp_out[0], 
482                         temp_out[1], 
483                         size, 
484                         1);
485         }
487         for(int i = 0; i < 2 && i < total_in_buffers; i++)
488         {
489                 double *out = output_ptr[i];
490                 float *in = temp_out[i];
491                 for(int j = 0; j < size; j++)
492                 {
493                         out[j] = gain_f * in[j];
494                 }
495         }
497         return 0;