add BC_SCALE env var for hi def monitors, cleanup theme data
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / delayaudio / delayaudio.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 "clip.h"
24 #include "bchash.h"
25 #include "delayaudio.h"
26 #include "filexml.h"
27 #include "language.h"
28 #include "samples.h"
29 #include "vframe.h"
30
31 #include <string.h>
32
33
34
35 PluginClient* new_plugin(PluginServer *server)
36 {
37         return new DelayAudio(server);
38 }
39
40
41 DelayAudio::DelayAudio(PluginServer *server)
42  : PluginAClient(server)
43 {
44         reset();
45 }
46
47 DelayAudio::~DelayAudio()
48 {
49
50
51         if(buffer) delete buffer;
52 }
53
54
55
56 NEW_WINDOW_MACRO(DelayAudio, DelayAudioWindow)
57
58 const char* DelayAudio::plugin_title() { return N_("Delay audio"); }
59 int DelayAudio::is_realtime() { return 1; }
60
61
62 void DelayAudio::reset()
63 {
64         need_reconfigure = 1;
65         buffer = 0;
66 }
67
68 int DelayAudio::load_configuration()
69 {
70         KeyFrame *prev_keyframe;
71         prev_keyframe = get_prev_keyframe(get_source_position());
72
73         DelayAudioConfig old_config;
74         old_config.copy_from(config);
75         read_data(prev_keyframe);
76
77         if(!old_config.equivalent(config))
78         {
79 // Reconfigure
80                 need_reconfigure = 1;
81                 return 1;
82         }
83         return 0;
84 }
85
86
87 void DelayAudio::read_data(KeyFrame *keyframe)
88 {
89         FileXML input;
90         input.set_shared_input(keyframe->xbuf);
91
92         int result = 0;
93         while(!result)
94         {
95                 result = input.read_tag();
96
97                 if(!result)
98                 {
99                         if(input.tag.title_is("DELAYAUDIO"))
100                         {
101                                 config.length = input.tag.get_property("LENGTH", (double)config.length);
102                         }
103                 }
104         }
105 }
106
107
108 void DelayAudio::save_data(KeyFrame *keyframe)
109 {
110         FileXML output;
111         output.set_shared_output(keyframe->xbuf);
112
113         output.tag.set_title("DELAYAUDIO");
114         output.tag.set_property("LENGTH", (double)config.length);
115         output.append_tag();
116         output.tag.set_title("/DELAYAUDIO");
117         output.append_tag();
118         output.append_newline();
119         output.terminate_string();
120 }
121
122 void DelayAudio::reconfigure()
123 {
124         input_start = (int64_t)(config.length * PluginAClient::project_sample_rate + 0.5);
125         int64_t new_allocation = input_start + PluginClient::in_buffer_size;
126         Samples *new_buffer = new Samples(new_allocation);
127         bzero(new_buffer->get_data(), sizeof(double) * new_allocation);
128
129 // printf("DelayAudio::reconfigure %f %d %d %d\n",
130 // config.length,
131 // PluginAClient::project_sample_rate,
132 // PluginClient::in_buffer_size,
133 // new_allocation);
134 //
135
136
137         if(buffer)
138         {
139                 int size = MIN(new_allocation, allocation);
140
141                 memcpy(new_buffer->get_data(),
142                         buffer->get_data(),
143                         (size - PluginClient::in_buffer_size) * sizeof(double));
144                 delete buffer;
145         }
146
147         allocation = new_allocation;
148         buffer = new_buffer;
149         allocation = new_allocation;
150         need_reconfigure = 0;
151 }
152
153 int DelayAudio::process_realtime(int64_t size, Samples *input_ptr, Samples *output_ptr)
154 {
155
156         load_configuration();
157         if(need_reconfigure) reconfigure();
158
159 // printf("DelayAudio::process_realtime %d %d\n",
160 // input_start, size);
161
162
163
164         double *buffer_samples = buffer->get_data();
165         double *output_samples = output_ptr->get_data();
166         double *input_samples = input_ptr->get_data();
167         memcpy(buffer_samples + input_start, input_samples, size * sizeof(double));
168         memcpy(output_samples, buffer_samples, size * sizeof(double));
169
170         for(int i = size, j = 0; i < allocation; i++, j++)
171         {
172                 buffer_samples[j] = buffer_samples[i];
173         }
174
175         return 0;
176 }
177
178
179
180
181 void DelayAudio::update_gui()
182 {
183         if(thread)
184         {
185                 load_configuration();
186                 ((DelayAudioWindow*)thread->window)->lock_window();
187                 ((DelayAudioWindow*)thread->window)->update_gui();
188                 ((DelayAudioWindow*)thread->window)->unlock_window();
189         }
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 DelayAudioWindow::DelayAudioWindow(DelayAudio *plugin)
208  : PluginClientWindow(plugin, xS(285), yS(80), xS(285), yS(80), 0)
209 {
210         this->plugin = plugin;
211 }
212
213 DelayAudioWindow::~DelayAudioWindow()
214 {
215 }
216
217 void DelayAudioWindow::create_objects()
218 {
219         int xs10 = xS(10);
220         int ys10 = yS(10), ys40 = yS(40);
221         add_subwindow(new BC_Title(xs10, ys10, _("Delay seconds:")));
222         length = new DelayAudioTextBox(
223                 plugin,
224                 this,
225                 xs10,
226                 ys40);
227         length->create_objects();
228         update_gui();
229         show_window();
230 }
231
232 void DelayAudioWindow::update_gui()
233 {
234         char string[BCTEXTLEN];
235         sprintf(string, "%.04f", plugin->config.length);
236         length->update(string);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250 DelayAudioTextBox::DelayAudioTextBox(
251         DelayAudio *plugin,
252         DelayAudioWindow *window,
253         int x,
254         int y)
255  : BC_TumbleTextBox(window,
256         (float)plugin->config.length,
257         (float)0,
258         (float)10,
259         x,
260         y,
261         100)
262 {
263         this->plugin = plugin;
264         set_increment(0.01);
265 }
266
267 DelayAudioTextBox::~DelayAudioTextBox()
268 {
269 }
270
271 int DelayAudioTextBox::handle_event()
272 {
273         plugin->config.length = atof(get_text());
274         if(plugin->config.length < 0) plugin->config.length = 0;
275         plugin->send_configure_change();
276         return 1;
277 }
278
279
280
281
282
283
284
285
286 DelayAudioConfig::DelayAudioConfig()
287 {
288         length = 1;
289 }
290
291 int DelayAudioConfig::equivalent(DelayAudioConfig &that)
292 {
293         return(EQUIV(this->length, that.length));
294 }
295
296 void DelayAudioConfig::copy_from(DelayAudioConfig &that)
297 {
298         this->length = that.length;
299 }
300
301
302
303
304