r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / level / leveleffect.C
blob4a91f50aeab843d858a30f57815a7b3616ea11f6
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "defaults.h"
4 #include "filesystem.h"
5 #include "filexml.h"
6 #include "leveleffect.h"
7 #include "picon_png.h"
8 #include "units.h"
9 #include "vframe.h"
11 #include <errno.h>
12 #include <math.h>
13 #include <string.h>
14 #include <unistd.h>
16 #include <libintl.h>
17 #define _(String) gettext(String)
18 #define gettext_noop(String) String
19 #define N_(String) gettext_noop (String)
29 REGISTER_PLUGIN(SoundLevelEffect)
39 SoundLevelConfig::SoundLevelConfig()
41         duration = 1.0;
44 void SoundLevelConfig::copy_from(SoundLevelConfig &that)
46         duration = that.duration;
49 int SoundLevelConfig::equivalent(SoundLevelConfig &that)
51         return EQUIV(duration, that.duration);
54 void SoundLevelConfig::interpolate(SoundLevelConfig &prev, 
55         SoundLevelConfig &next, 
56         int64_t prev_frame, 
57         int64_t next_frame, 
58         int64_t current_frame)
60         duration = prev.duration;
77 SoundLevelDuration::SoundLevelDuration(SoundLevelEffect *plugin, int x, int y)
78  : BC_FSlider(x, y, 0, 180, 180, 0.0, 10.0, plugin->config.duration)
80         this->plugin = plugin;
81         set_precision(0.1);
84 int SoundLevelDuration::handle_event()
86         plugin->config.duration = get_value();
87         plugin->send_configure_change();
88         return 1;
93 SoundLevelWindow::SoundLevelWindow(SoundLevelEffect *plugin, int x, int y)
94  : BC_Window(plugin->gui_string, 
95         x, 
96         y, 
97         350, 
98         120, 
99         350, 
100         120,
101         0, 
102         0,
103         1)
105         this->plugin = plugin;
108 void SoundLevelWindow::create_objects()
110 //printf("SoundLevelWindow::create_objects 1\n");
111         int x = 10, y = 10;
114         add_subwindow(new BC_Title(x, y, _("Duration (seconds):")));
115         add_subwindow(duration = new SoundLevelDuration(plugin, x + 150, y));
116         y += 35;
117         add_subwindow(new BC_Title(x, y, _("Max soundlevel (dB):")));
118         add_subwindow(soundlevel_max = new BC_Title(x + 150, y, "0.0"));
119         y += 35;
120         add_subwindow(new BC_Title(x, y, _("RMS soundlevel (dB):")));
121         add_subwindow(soundlevel_rms = new BC_Title(x + 150, y, "0.0"));
123         show_window();
124         flush();
125 //printf("SoundLevelWindow::create_objects 2\n");
128 WINDOW_CLOSE_EVENT(SoundLevelWindow)
140 PLUGIN_THREAD_OBJECT(SoundLevelEffect, SoundLevelThread, SoundLevelWindow)
156 SoundLevelEffect::SoundLevelEffect(PluginServer *server)
157  : PluginAClient(server)
159         PLUGIN_CONSTRUCTOR_MACRO
160         reset();
163 SoundLevelEffect::~SoundLevelEffect()
165         PLUGIN_DESTRUCTOR_MACRO
168 NEW_PICON_MACRO(SoundLevelEffect)
170 LOAD_CONFIGURATION_MACRO(SoundLevelEffect, SoundLevelConfig)
172 SHOW_GUI_MACRO(SoundLevelEffect, SoundLevelThread)
174 RAISE_WINDOW_MACRO(SoundLevelEffect)
176 SET_STRING_MACRO(SoundLevelEffect)
179 void SoundLevelEffect::reset()
181         rms_accum = 0;
182         max_accum = 0;
183         accum_size = 0;
186 char* SoundLevelEffect::plugin_title()
188         return _("SoundLevel");
192 int SoundLevelEffect::is_realtime()
194         return 1;
197 void SoundLevelEffect::read_data(KeyFrame *keyframe)
199         FileXML input;
200         input.set_shared_string(keyframe->data, strlen(keyframe->data));
202         int result = 0;
203         while(!result)
204         {
205                 result = input.read_tag();
207                 if(!result)
208                 {
209                         if(input.tag.title_is("SOUNDLEVEL"))
210                         {
211                                 config.duration = input.tag.get_property("DURATION", config.duration);
212                         }
213                 }
214         }
217 void SoundLevelEffect::save_data(KeyFrame *keyframe)
219         FileXML output;
220         output.set_shared_string(keyframe->data, MESSAGESIZE);
222         output.tag.set_title("SOUNDLEVEL");
223         output.tag.set_property("DURATION", config.duration);
224         output.append_tag();
225         output.append_newline();
227         output.terminate_string();
230 int SoundLevelEffect::load_defaults()
232         defaults = new Defaults(BCASTDIR "soundlevel.rc");
233         defaults->load();
235         config.duration = defaults->get("DURATION", config.duration);
236         return 0;
239 int SoundLevelEffect::save_defaults()
241         defaults->update("DURATION", config.duration);
242         defaults->save();
244         return 0;
247 void SoundLevelEffect::update_gui()
249 //printf("SoundLevelEffect::update_gui 1\n");
250         if(thread)
251         {
252                 load_configuration();
253                 thread->window->lock_window();
254                 thread->window->duration->update(config.duration);
255                 thread->window->unlock_window();
256         }
257 //printf("SoundLevelEffect::update_gui 2\n");
260 int SoundLevelEffect::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
262         load_configuration();
264         accum_size += size;
265         for(int i = 0; i < size; i++)
266         {
267                 double value = fabs(input_ptr[i]);
268                 if(value > max_accum) max_accum = value;
269                 rms_accum += value * value;
270         }
272         if(accum_size > config.duration * PluginAClient::project_sample_rate)
273         {
274 //printf("SoundLevelEffect::process_realtime 1 %f %d\n", rms_accum, accum_size);
275                 rms_accum = sqrt(rms_accum / accum_size);
276                 double arg[2];
277                 arg[0] = max_accum;
278                 arg[1] = rms_accum;
279                 send_render_gui(arg, 2);
280                 rms_accum = 0;
281                 max_accum = 0;
282                 accum_size = 0;
283         }
284         return 0;
287 void SoundLevelEffect::render_gui(void *data, int size)
289         if(thread)
290         {
291                 thread->window->lock_window();
292                 char string[BCTEXTLEN];
293                 double *arg = (double*)data;
294                 sprintf(string, "%.2f", DB::todb(arg[0]));
295                 thread->window->soundlevel_max->update(string);
296                 sprintf(string, "%.2f", DB::todb(arg[1]));
297                 thread->window->soundlevel_rms->update(string);
298                 thread->window->flush();
299                 thread->window->unlock_window();
300         }