bg/clr color tweaks, clear borders rework, fc31 depends
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / overlayaudio / overlayaudio.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "bchash.h"
24 #include "filexml.h"
25 #include "language.h"
26 #include "pluginaclient.h"
27 #include "samples.h"
28 #include "theme.h"
29 #include <string.h>
30
31
32 class OverlayAudioWindow;
33 class OverlayAudio;
34
35 #define AUDIO_TRANSFER_TYPES 2
36
37
38 class OverlayAudioConfig
39 {
40 public:
41         OverlayAudioConfig();
42         int equivalent(OverlayAudioConfig &that);
43         void copy_from(OverlayAudioConfig &that);
44         void interpolate(OverlayAudioConfig &prev,
45                 OverlayAudioConfig &next,
46                 int64_t prev_frame,
47                 int64_t next_frame,
48                 int64_t current_frame);
49         static const char* output_to_text(int output_layer);
50         static const char* mode_to_text(int mode);
51         int output_track;
52         enum
53         {
54                 TOP,
55                 BOTTOM
56         };
57
58
59         int mode;
60         enum
61         {
62                 ADD,
63                 MULTIPLY
64         };
65 };
66
67 class OutputTrack : public BC_PopupMenu
68 {
69 public:
70         OutputTrack(OverlayAudio *plugin, int x, int y);
71         void create_objects();
72         int handle_event();
73         OverlayAudio *plugin;
74 };
75
76
77 class OverlayMode : public BC_PopupMenu
78 {
79 public:
80         OverlayMode(OverlayAudio *plugin,
81                 int x,
82                 int y);
83         void create_objects();
84         int handle_event();
85         OverlayAudio *plugin;
86 };
87
88 class OverlayAudioWindow : public PluginClientWindow
89 {
90 public:
91         OverlayAudioWindow(OverlayAudio *plugin);
92
93         void create_objects();
94
95
96         OverlayAudio *plugin;
97         OutputTrack *output;
98         OverlayMode *mode;
99 };
100
101
102
103 class OverlayAudio : public PluginAClient
104 {
105 public:
106         OverlayAudio(PluginServer *server);
107         ~OverlayAudio();
108
109         int is_multichannel();
110         int is_realtime();
111         void read_data(KeyFrame *keyframe);
112         void save_data(KeyFrame *keyframe);
113         int process_buffer(int64_t size,
114                 Samples **buffer,
115                 int64_t start_position,
116                 int sample_rate);
117         void update_gui();
118
119
120         PLUGIN_CLASS_MEMBERS2(OverlayAudioConfig)
121 };
122
123
124
125
126
127
128
129
130 OverlayAudioConfig::OverlayAudioConfig()
131 {
132         output_track = OverlayAudioConfig::TOP;
133         mode = OverlayAudioConfig::ADD;
134
135 }
136
137 int OverlayAudioConfig::equivalent(OverlayAudioConfig &that)
138 {
139         return that.output_track == output_track &&
140                 that.mode == mode;
141 }
142
143 void OverlayAudioConfig::copy_from(OverlayAudioConfig &that)
144 {
145         output_track = that.output_track;
146         mode = that.mode;
147 }
148
149 void OverlayAudioConfig::interpolate(OverlayAudioConfig &prev,
150         OverlayAudioConfig &next,
151         int64_t prev_frame,
152         int64_t next_frame,
153         int64_t current_frame)
154 {
155         output_track = prev.output_track;
156         mode = prev.mode;
157 }
158
159 const char* OverlayAudioConfig::output_to_text(int output_layer)
160 {
161         switch(output_layer)
162         {
163                 case OverlayAudioConfig::TOP:    return _("Top");
164                 case OverlayAudioConfig::BOTTOM: return _("Bottom");
165         }
166         return "";
167 }
168
169
170 const char* OverlayAudioConfig::mode_to_text(int mode)
171 {
172         switch(mode)
173         {
174                 case OverlayAudioConfig::ADD:    return _("Add");
175                 case OverlayAudioConfig::MULTIPLY: return _("Multiply");
176         }
177         return "";
178 }
179
180
181
182
183
184
185
186 OverlayAudioWindow::OverlayAudioWindow(OverlayAudio *plugin)
187  : PluginClientWindow(plugin,
188         xS(300),
189         yS(70),
190         xS(300),
191         yS(70),
192         0)
193 {
194         this->plugin = plugin;
195 }
196
197 void OverlayAudioWindow::create_objects()
198 {
199         int x = xS(10), y = yS(10);
200         int x1 = x;
201         BC_Title *title;
202         add_subwindow(title = new BC_Title(x, y, _("Output track:")));
203         x += title->get_w() + plugin->get_theme()->widget_border;
204         add_subwindow(output = new OutputTrack(plugin, x, y));
205         output->create_objects();
206
207         y += output->get_h() + plugin->get_theme()->widget_border;
208         x = x1;
209         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
210         x += title->get_w() + plugin->get_theme()->widget_border;
211         add_subwindow(mode = new OverlayMode(plugin, x, y));
212         mode->create_objects();
213
214
215         show_window();
216 }
217
218
219
220
221
222
223 OutputTrack::OutputTrack(OverlayAudio *plugin, int x , int y)
224  : BC_PopupMenu(x, y, xS(100),
225         OverlayAudioConfig::output_to_text(plugin->config.output_track),
226         1)
227 {
228         this->plugin = plugin;
229 }
230
231 void OutputTrack::create_objects()
232 {
233         add_item(new BC_MenuItem(
234                 OverlayAudioConfig::output_to_text(
235                         OverlayAudioConfig::TOP)));
236         add_item(new BC_MenuItem(
237                 OverlayAudioConfig::output_to_text(
238                         OverlayAudioConfig::BOTTOM)));
239 }
240
241 int OutputTrack::handle_event()
242 {
243         char *text = get_text();
244
245         if(!strcmp(text,
246                 OverlayAudioConfig::output_to_text(
247                         OverlayAudioConfig::TOP)))
248                 plugin->config.output_track = OverlayAudioConfig::TOP;
249         else
250         if(!strcmp(text,
251                 OverlayAudioConfig::output_to_text(
252                         OverlayAudioConfig::BOTTOM)))
253                 plugin->config.output_track = OverlayAudioConfig::BOTTOM;
254
255         plugin->send_configure_change();
256         return 1;
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270 OverlayMode::OverlayMode(OverlayAudio *plugin, int x, int y)
271  : BC_PopupMenu(x, y, xS(150),
272         OverlayAudioConfig::mode_to_text(plugin->config.mode),
273         1)
274 {
275         this->plugin = plugin;
276 }
277
278 void OverlayMode::create_objects()
279 {
280         for(int i = 0; i < AUDIO_TRANSFER_TYPES; i++)
281                 add_item(new BC_MenuItem(OverlayAudioConfig::mode_to_text(i)));
282 }
283
284 int OverlayMode::handle_event()
285 {
286         char *text = get_text();
287
288         for(int i = 0; i < AUDIO_TRANSFER_TYPES; i++)
289         {
290                 if(!strcmp(text, OverlayAudioConfig::mode_to_text(i)))
291                 {
292                         plugin->config.mode = i;
293                         break;
294                 }
295         }
296
297         plugin->send_configure_change();
298         return 1;
299 }
300
301
302
303
304
305
306
307
308
309 REGISTER_PLUGIN(OverlayAudio)
310
311
312
313
314 OverlayAudio::OverlayAudio(PluginServer *server)
315  : PluginAClient(server)
316 {
317
318 }
319
320 OverlayAudio::~OverlayAudio()
321 {
322
323 }
324
325 const char* OverlayAudio::plugin_title() { return N_("Overlay"); }
326 int OverlayAudio::is_realtime() { return 1; }
327 int OverlayAudio::is_multichannel() { return 1; }
328
329
330
331 void OverlayAudio::read_data(KeyFrame *keyframe)
332 {
333         FileXML input;
334         input.set_shared_input(keyframe->xbuf);
335
336         int result = 0;
337         while(!result)
338         {
339                 result = input.read_tag();
340
341                 if(!result)
342                 {
343                         if(input.tag.title_is("OVERLAY"))
344                         {
345                                 config.output_track = input.tag.get_property("OUTPUT", config.output_track);
346                                 config.mode = input.tag.get_property("MODE", config.mode);
347                         }
348                 }
349         }
350 }
351
352 void OverlayAudio::save_data(KeyFrame *keyframe)
353 {
354         FileXML output;
355         output.set_shared_output(keyframe->xbuf);
356
357         output.tag.set_title("OVERLAY");
358         output.tag.set_property("OUTPUT", config.output_track);
359         output.tag.set_property("MODE", config.mode);
360         output.append_tag();
361         output.tag.set_title("/OVERLAY");
362         output.append_tag();
363         output.append_newline();
364         output.terminate_string();
365 }
366
367
368
369 void OverlayAudio::update_gui()
370 {
371         if(thread)
372         {
373                 if(load_configuration())
374                 {
375                         thread->window->lock_window("OverlayAudio::update_gui");
376                         ((OverlayAudioWindow*)thread->window)->output->set_text(
377                                 OverlayAudioConfig::output_to_text(config.output_track));
378                         ((OverlayAudioWindow*)thread->window)->mode->set_text(
379                                 OverlayAudioConfig::mode_to_text(config.mode));
380                         thread->window->unlock_window();
381                 }
382         }
383 }
384
385 NEW_WINDOW_MACRO(OverlayAudio, OverlayAudioWindow)
386 LOAD_CONFIGURATION_MACRO(OverlayAudio, OverlayAudioConfig)
387
388
389 int OverlayAudio::process_buffer(int64_t size,
390         Samples **buffer,
391         int64_t start_position,
392         int sample_rate)
393 {
394         load_configuration();
395
396
397         int output_track = 0;
398         if(config.output_track == OverlayAudioConfig::BOTTOM)
399                 output_track = get_total_buffers() - 1;
400
401 // Direct copy the output track
402         read_samples(buffer[output_track],
403                 output_track,
404                 sample_rate,
405                 start_position,
406                 size);
407
408 // Add remaining tracks
409         Samples *output_buffer = buffer[output_track];
410         double *output_samples = output_buffer->get_data();
411         for(int i = 0; i < get_total_buffers(); i++)
412         {
413                 if(i != output_track)
414                 {
415                         Samples *input_buffer = buffer[i];
416                         read_samples(buffer[i],
417                                 i,
418                                 sample_rate,
419                                 start_position,
420                                 size);
421                         double *input_samples = input_buffer->get_data();
422
423                         switch(config.mode)
424                         {
425                                 case OverlayAudioConfig::ADD:
426                                         for(int j = 0; j < size; j++)
427                                         {
428                                                 output_samples[j] += input_samples[j];
429                                         }
430                                         break;
431
432
433                                 case OverlayAudioConfig::MULTIPLY:
434                                         for(int j = 0; j < size; j++)
435                                         {
436                                                 output_samples[j] *= input_samples[j];
437                                         }
438                                         break;
439                         }
440                 }
441         }
442
443         return 0;
444 }
445
446
447
448
449
450