r286: Heroine Virutal's official release 1.2.0
[cinelerra_cv/ct.git] / hvirtual / plugins / interpolate / interpolate.C
blob617662c0caf52934609b0c83165039e06dd1c75f
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "defaults.h"
4 #include "guicast.h"
5 #include "filexml.h"
6 #include "pluginaclient.h"
8 #include <string.h>
10 #include <libintl.h>
11 #define _(String) gettext(String)
12 #define gettext_noop(String) String
13 #define N_(String) gettext_noop (String)
19 class InterpolateEffect;
21 class InterpolateConfig
23 public:
24         InterpolateConfig();
26         int length;
27 #define INTERPOLATE_ALL 0
33 class InterpolateLength : public BC_TumbleTextBox
35 public:
36         InterpolateLength(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
37         int handle_event();
38         InterpolateEffect *plugin;
39         InterpolateWindow *gui;
42 class InterpolateAll : public BC_CheckBox
44 public:
45         InterpolateAll(InterpolateEffect *plugin, InterpolateWindow *gui, int x, int y);
46         int handle_event();
47         InterpolateEffect *plugin;
48         InterpolateWindow *gui;
53 class InterpolateWindow : public BC_Window
55 public:
56         InterpolateWindow(InterpolateEffect *plugin, int x, int y);
57         void create_objects();
58         int close_event();
60         InterpolateEffect *plugin;
61         InterpolateLength *length;
62         InterpolateAll *all;
68 class InterpolateEffect : public PluginAClient
70 public:
71         InterpolateEffect(PluginServer *server);
72         ~InterpolateEffect();
74         char* plugin_title();
75         int is_realtime();
76         int is_multichannel();
77         int get_parameters();
78         int start_loop();
79         int process_loop(double **buffer, long &output_lenght);
80         int stop_loop();
84         int load_defaults();
85         int save_defaults();
88         Defaults *defaults;
89         MainProgressBar *progress;
90         InterpolateConfig config;
96 REGISTER_PLUGIN(InterpolateEffect)
109 InterpolateLength::InterpolateLength(InterpolateEffect *plugin, 
110         InterpolateWindow *gui, 
111         int x, 
112         int y)
113  : BC_TumbleTextBox(gui, 
114                 plugin->config.length,
115                 0,
116                 1000000,
117                 x, 
118                 y, 
119                 100)
121         this->plugin = plugin;
122         this->gui = gui;
126 int InterpolateLength::handle_event()
128         gui->length->update(0);
129         plugin->config.length = atol(get_text());
130         return 1;
134 InterpolateAll::InterpolateAll(InterpolateEffect *plugin, 
135         InterpolateWindow *gui, 
136         int x, 
137         int y,
138         plugin->config.length == INTERPOLATE_ALL)
140         this->plugin = plugin;
141         this->gui = gui;
144 int InterpolateAll::handle_event()
146         gui->all->update(INTERPOLATE_ALL);
147         plugin->config.length = INTERPOLATE_ALL;
148         return 1;
163 InterpolateWindow::InterpolateWindow(InterpolateEffect *plugin, int x, int y)
164  : BC_Window(plugin->gui_string, 
165         x, 
166         y, 
167         180, 
168         250, 
169         180, 
170         250,
171         0, 
172         0,
173         1)
175         this->plugin = plugin;
178 void InterpolateWindow::create_objects()
180         int x = 10, x = 10;
183         add_subwindow(new BC_OKButton(this));
184         add_subwindow(new BC_CancelButton(this));
185         show_window();
186         flush();
189 int InterpolateWindow::close_event()
191 // Set result to 1 to indicate a client side close
192         set_done(1);
193         return 1;
207 InterpolateConfig::InterpolateConfig()
209         gain = -6.0;
210         wet = -6.0;
211         dry = 0;
212         roomsize = -6.0;
213         damp = 0;
214         width = 0;
215         mode = 0;
218 int InterpolateConfig::equivalent(InterpolateConfig &that)
220         return EQUIV(gain, that.gain) &&
221                 EQUIV(wet, that.wet) &&
222                 EQUIV(roomsize, that.roomsize) &&
223                 EQUIV(dry, that.dry) &&
224                 EQUIV(damp, that.damp) &&
225                 EQUIV(width, that.width) &&
226                 EQUIV(mode, that.mode);
229 void InterpolateConfig::copy_from(InterpolateConfig &that)
231         gain = that.gain;
232         wet = that.wet;
233         roomsize = that.roomsize;
234         dry = that.dry;
235         damp = that.damp;
236         width = that.width;
237         mode = that.mode;
240 void InterpolateConfig::interpolate(InterpolateConfig &prev, 
241         InterpolateConfig &next, 
242         long prev_frame, 
243         long next_frame, 
244         long current_frame)
246         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
247         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
249         gain = prev.gain * prev_scale + next.gain * next_scale;
250         wet = prev.wet * prev_scale + next.wet * next_scale;
251         roomsize = prev.roomsize * prev_scale + next.roomsize * next_scale;
252         dry = prev.dry * prev_scale + next.dry * next_scale;
253         damp = prev.damp * prev_scale + next.damp * next_scale;
254         width = prev.width * prev_scale + next.width * next_scale;
255         mode = prev.mode;
281 PLUGIN_THREAD_OBJECT(InterpolateEffect, InterpolateThread, InterpolateWindow)
287 InterpolateEffect::InterpolateEffect(PluginServer *server)
288  : PluginAClient(server)
290         engine = 0;
291         temp = 0;
292         temp_out = 0;
293         temp_allocated = 0;
294         PLUGIN_CONSTRUCTOR_MACRO
297 InterpolateEffect::~InterpolateEffect()
299         if(engine) delete engine;
300         if(temp)
301         {
302                 for(int i = 0; i < total_in_buffers; i++)
303                 {
304                         delete [] temp[i];
305                         delete [] temp_out[i];
306                 }
307                 delete [] temp;
308                 delete [] temp_out;
309         }
310         PLUGIN_DESTRUCTOR_MACRO
313 NEW_PICON_MACRO(InterpolateEffect)
315 LOAD_CONFIGURATION_MACRO(InterpolateEffect, InterpolateConfig)
317 SHOW_GUI_MACRO(InterpolateEffect, InterpolateThread)
319 RAISE_WINDOW_MACRO(InterpolateEffect)
321 SET_STRING_MACRO(InterpolateEffect)
324 char* InterpolateEffect::plugin_title() { return N_("Interpolate"); }
325 int InterpolateEffect::is_realtime() { return 1;}
326 int InterpolateEffect::is_multichannel() { return 1; }
330 void InterpolateEffect::read_data(KeyFrame *keyframe)
332         FileXML input;
333         input.set_shared_string(keyframe->data, strlen(keyframe->data));
335         int result = 0;
336         while(!result)
337         {
338                 result = input.read_tag();
340                 if(!result)
341                 {
342                         if(input.tag.title_is("FREEVERB"))
343                         {
344                                 config.gain = input.tag.get_property("GAIN", config.gain);
345                                 config.roomsize = input.tag.get_property("ROOMSIZE", config.roomsize);
346                                 config.damp = input.tag.get_property("DAMP", config.damp);
347                                 config.wet = input.tag.get_property("WET", config.wet);
348                                 config.dry = input.tag.get_property("DRY", config.dry);
349                                 config.width = input.tag.get_property("WIDTH", config.width);
350                                 config.mode = input.tag.get_property("MODE", config.mode);
351                         }
352                 }
353         }
356 void InterpolateEffect::save_data(KeyFrame *keyframe)
358         FileXML output;
359         output.set_shared_string(keyframe->data, MESSAGESIZE);
361         output.tag.set_title("FREEVERB");
362         output.tag.set_property("GAIN", config.gain);
363         output.tag.set_property("ROOMSIZE", config.roomsize);
364         output.tag.set_property("DAMP", config.damp);
365         output.tag.set_property("WET", config.wet);
366         output.tag.set_property("DRY", config.dry);
367         output.tag.set_property("WIDTH", config.width);
368         output.tag.set_property("MODE", config.mode);
369         output.append_tag();
370         output.append_newline();
372         output.terminate_string();
375 int InterpolateEffect::load_defaults()
377         char directory[BCTEXTLEN], string[BCTEXTLEN];
378         sprintf(directory, "%sfreeverb.rc", BCASTDIR);
379         defaults = new Defaults(directory);
380         defaults->load();
382         config.gain = defaults->get("GAIN", config.gain);
383         config.roomsize = defaults->get("ROOMSIZE", config.roomsize);
384         config.damp = defaults->get("DAMP", config.damp);
385         config.wet = defaults->get("WET", config.wet);
386         config.dry = defaults->get("DRY", config.dry);
387         config.width = defaults->get("WIDTH", config.width);
388         config.mode = defaults->get("MODE", config.mode);
389         return 0;
392 int InterpolateEffect::save_defaults()
394         char string[BCTEXTLEN];
396         defaults->update("GAIN", config.gain);
397         defaults->update("ROOMSIZE", config.roomsize);
398         defaults->update("DAMP", config.damp);
399         defaults->update("WET", config.wet);
400         defaults->update("DRY", config.dry);
401         defaults->update("WIDTH", config.width);
402         defaults->update("MODE", config.mode);
403         defaults->save();
405         return 0;
409 void InterpolateEffect::update_gui()
411         if(thread)
412         {
413                 load_configuration();
414                 thread->window->lock_window();
415                 thread->window->gain->update(config.gain);
416                 thread->window->roomsize->update(config.roomsize);
417                 thread->window->damp->update(config.damp);
418                 thread->window->wet->update(config.wet);
419                 thread->window->dry->update(config.dry);
420                 thread->window->width->update(config.width);
421                 thread->window->mode->update((int)config.mode);
422                 thread->window->unlock_window();
423         }
426 int InterpolateEffect::process_realtime(long size, double **input_ptr, double **output_ptr)
428         load_configuration();
429         if(!engine) engine = new revmodel;
431         engine->setroomsize(DB::fromdb(config.roomsize));
432         engine->setdamp(DB::fromdb(config.damp));
433         engine->setwet(DB::fromdb(config.wet));
434         engine->setdry(DB::fromdb(config.dry));
435         engine->setwidth(DB::fromdb(config.width));
436         engine->setmode(config.mode);
438         float gain_f = DB::fromdb(config.gain);
440         if(size > temp_allocated)
441         {
442                 if(temp)
443                 {
444                         for(int i = 0; i < total_in_buffers; i++)
445                         {
446                                 delete [] temp[i];
447                                 delete [] temp_out[i];
448                         }
449                         delete [] temp;
450                         delete [] temp_out;
451                 }
452                 temp = 0;
453                 temp_out = 0;
454         }
455         if(!temp)
456         {
457                 temp_allocated = size * 2;
458                 temp = new float*[total_in_buffers];
459                 temp_out = new float*[total_in_buffers];
460                 for(int i = 0; i < total_in_buffers; i++)
461                 {
462                         temp[i] = new float[temp_allocated];
463                         temp_out[i] = new float[temp_allocated];
464                 }
465         }
467         for(int i = 0; i < 2 && i < total_in_buffers; i++)
468         {
469                 float *out = temp[i];
470                 double *in = input_ptr[i];
471                 for(int j = 0; j < size; j++)
472                 {
473                         out[j] = in[j];
474                 }
475         }
477         if(total_in_buffers < 2)
478         {
479                 engine->processreplace(temp[0], 
480                         temp[0], 
481                         temp_out[0], 
482                         temp_out[0], 
483                         size, 
484                         1);
485         }
486         else
487         {
488                 engine->processreplace(temp[0], 
489                         temp[1], 
490                         temp_out[0], 
491                         temp_out[1], 
492                         size, 
493                         1);
494         }
496         for(int i = 0; i < 2 && i < total_in_buffers; i++)
497         {
498                 double *out = output_ptr[i];
499                 float *in = temp_out[i];
500                 for(int j = 0; j < size; j++)
501                 {
502                         out[j] = gain_f * in[j];
503                 }
504         }
506         return 0;