r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / interpolate / interpolate.C
blobc70cec2a810e878f586fb9e42f639486313e761e
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()
326         return _("Interpolate");
330 int InterpolateEffect::is_realtime()
332         return 1;
335 int InterpolateEffect::is_multichannel()
337         return 1;
342 void InterpolateEffect::read_data(KeyFrame *keyframe)
344         FileXML input;
345         input.set_shared_string(keyframe->data, strlen(keyframe->data));
347         int result = 0;
348         while(!result)
349         {
350                 result = input.read_tag();
352                 if(!result)
353                 {
354                         if(input.tag.title_is("FREEVERB"))
355                         {
356                                 config.gain = input.tag.get_property("GAIN", config.gain);
357                                 config.roomsize = input.tag.get_property("ROOMSIZE", config.roomsize);
358                                 config.damp = input.tag.get_property("DAMP", config.damp);
359                                 config.wet = input.tag.get_property("WET", config.wet);
360                                 config.dry = input.tag.get_property("DRY", config.dry);
361                                 config.width = input.tag.get_property("WIDTH", config.width);
362                                 config.mode = input.tag.get_property("MODE", config.mode);
363                         }
364                 }
365         }
368 void InterpolateEffect::save_data(KeyFrame *keyframe)
370         FileXML output;
371         output.set_shared_string(keyframe->data, MESSAGESIZE);
373         output.tag.set_title("FREEVERB");
374         output.tag.set_property("GAIN", config.gain);
375         output.tag.set_property("ROOMSIZE", config.roomsize);
376         output.tag.set_property("DAMP", config.damp);
377         output.tag.set_property("WET", config.wet);
378         output.tag.set_property("DRY", config.dry);
379         output.tag.set_property("WIDTH", config.width);
380         output.tag.set_property("MODE", config.mode);
381         output.append_tag();
382         output.append_newline();
384         output.terminate_string();
387 int InterpolateEffect::load_defaults()
389         char directory[BCTEXTLEN], string[BCTEXTLEN];
390         sprintf(directory, "%sfreeverb.rc", BCASTDIR);
391         defaults = new Defaults(directory);
392         defaults->load();
394         config.gain = defaults->get("GAIN", config.gain);
395         config.roomsize = defaults->get("ROOMSIZE", config.roomsize);
396         config.damp = defaults->get("DAMP", config.damp);
397         config.wet = defaults->get("WET", config.wet);
398         config.dry = defaults->get("DRY", config.dry);
399         config.width = defaults->get("WIDTH", config.width);
400         config.mode = defaults->get("MODE", config.mode);
401         return 0;
404 int InterpolateEffect::save_defaults()
406         char string[BCTEXTLEN];
408         defaults->update("GAIN", config.gain);
409         defaults->update("ROOMSIZE", config.roomsize);
410         defaults->update("DAMP", config.damp);
411         defaults->update("WET", config.wet);
412         defaults->update("DRY", config.dry);
413         defaults->update("WIDTH", config.width);
414         defaults->update("MODE", config.mode);
415         defaults->save();
417         return 0;
421 void InterpolateEffect::update_gui()
423         if(thread)
424         {
425                 load_configuration();
426                 thread->window->lock_window();
427                 thread->window->gain->update(config.gain);
428                 thread->window->roomsize->update(config.roomsize);
429                 thread->window->damp->update(config.damp);
430                 thread->window->wet->update(config.wet);
431                 thread->window->dry->update(config.dry);
432                 thread->window->width->update(config.width);
433                 thread->window->mode->update((int)config.mode);
434                 thread->window->unlock_window();
435         }
438 int InterpolateEffect::process_realtime(long size, double **input_ptr, double **output_ptr)
440         load_configuration();
441         if(!engine) engine = new revmodel;
443         engine->setroomsize(DB::fromdb(config.roomsize));
444         engine->setdamp(DB::fromdb(config.damp));
445         engine->setwet(DB::fromdb(config.wet));
446         engine->setdry(DB::fromdb(config.dry));
447         engine->setwidth(DB::fromdb(config.width));
448         engine->setmode(config.mode);
450         float gain_f = DB::fromdb(config.gain);
452         if(size > temp_allocated)
453         {
454                 if(temp)
455                 {
456                         for(int i = 0; i < total_in_buffers; i++)
457                         {
458                                 delete [] temp[i];
459                                 delete [] temp_out[i];
460                         }
461                         delete [] temp;
462                         delete [] temp_out;
463                 }
464                 temp = 0;
465                 temp_out = 0;
466         }
467         if(!temp)
468         {
469                 temp_allocated = size * 2;
470                 temp = new float*[total_in_buffers];
471                 temp_out = new float*[total_in_buffers];
472                 for(int i = 0; i < total_in_buffers; i++)
473                 {
474                         temp[i] = new float[temp_allocated];
475                         temp_out[i] = new float[temp_allocated];
476                 }
477         }
479         for(int i = 0; i < 2 && i < total_in_buffers; i++)
480         {
481                 float *out = temp[i];
482                 double *in = input_ptr[i];
483                 for(int j = 0; j < size; j++)
484                 {
485                         out[j] = in[j];
486                 }
487         }
489         if(total_in_buffers < 2)
490         {
491                 engine->processreplace(temp[0], 
492                         temp[0], 
493                         temp_out[0], 
494                         temp_out[0], 
495                         size, 
496                         1);
497         }
498         else
499         {
500                 engine->processreplace(temp[0], 
501                         temp[1], 
502                         temp_out[0], 
503                         temp_out[1], 
504                         size, 
505                         1);
506         }
508         for(int i = 0; i < 2 && i < total_in_buffers; i++)
509         {
510                 double *out = output_ptr[i];
511                 float *in = temp_out[i];
512                 for(int j = 0; j < size; j++)
513                 {
514                         out[j] = gain_f * in[j];
515                 }
516         }
518         return 0;