plugin fixes and upgrades
[goodguy/history.git] / cinelerra-5.0 / 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 _("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->get_data(), strlen(keyframe->get_data()));
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->get_data(), MESSAGESIZE);
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, 
209         200, 
210         80, 
211         200, 
212         80, 
213         0)
214 {
215         this->plugin = plugin;
216 }
217
218 DelayAudioWindow::~DelayAudioWindow()
219 {
220 }
221
222 void DelayAudioWindow::create_objects()
223 {
224         add_subwindow(new BC_Title(10, 10, _("Delay seconds:")));
225         length = new DelayAudioTextBox(
226                 plugin, 
227                 this,
228                 10, 
229                 40);
230         length->create_objects();
231         update_gui();
232         show_window();
233 }
234
235 void DelayAudioWindow::update_gui()
236 {
237         char string[BCTEXTLEN];
238         sprintf(string, "%.04f", plugin->config.length);
239         length->update(string);
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253 DelayAudioTextBox::DelayAudioTextBox(
254         DelayAudio *plugin, 
255         DelayAudioWindow *window,
256         int x, 
257         int y)
258  : BC_TumbleTextBox(window,
259         (float)plugin->config.length,
260         (float)0,
261         (float)10,
262         x, 
263         y, 
264         100)
265 {
266         this->plugin = plugin;
267         set_increment(0.01);
268 }
269
270 DelayAudioTextBox::~DelayAudioTextBox()
271 {
272 }
273
274 int DelayAudioTextBox::handle_event()
275 {
276         plugin->config.length = atof(get_text());
277         if(plugin->config.length < 0) plugin->config.length = 0;
278         plugin->send_configure_change();
279         return 1;
280 }
281
282
283
284
285
286
287
288
289 DelayAudioConfig::DelayAudioConfig()
290 {
291         length = 1;
292 }
293         
294 int DelayAudioConfig::equivalent(DelayAudioConfig &that)
295 {
296         return(EQUIV(this->length, that.length));
297 }
298
299 void DelayAudioConfig::copy_from(DelayAudioConfig &that)
300 {
301         this->length = that.length;
302 }
303
304
305
306
307