6c95582cbebb852e9946b2f456401faf7dc4bb28
[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.append_newline();
117         output.terminate_string();
118 }
119
120 void DelayAudio::reconfigure()
121 {
122         input_start = (int64_t)(config.length * PluginAClient::project_sample_rate + 0.5);
123         int64_t new_allocation = input_start + PluginClient::in_buffer_size;
124         Samples *new_buffer = new Samples(new_allocation);
125         bzero(new_buffer->get_data(), sizeof(double) * new_allocation);
126
127 // printf("DelayAudio::reconfigure %f %d %d %d\n", 
128 // config.length, 
129 // PluginAClient::project_sample_rate, 
130 // PluginClient::in_buffer_size,
131 // new_allocation);
132 // 
133
134
135         if(buffer)
136         {
137                 int size = MIN(new_allocation, allocation);
138
139                 memcpy(new_buffer->get_data(), 
140                         buffer->get_data(), 
141                         (size - PluginClient::in_buffer_size) * sizeof(double));
142                 delete buffer;
143         }
144
145         allocation = new_allocation;
146         buffer = new_buffer;
147         allocation = new_allocation;
148         need_reconfigure = 0;
149 }
150
151 int DelayAudio::process_realtime(int64_t size, Samples *input_ptr, Samples *output_ptr)
152 {
153
154         load_configuration();
155         if(need_reconfigure) reconfigure();
156
157 // printf("DelayAudio::process_realtime %d %d\n",
158 // input_start, size);
159
160
161
162         double *buffer_samples = buffer->get_data();
163         double *output_samples = output_ptr->get_data();
164         double *input_samples = input_ptr->get_data();
165         memcpy(buffer_samples + input_start, input_samples, size * sizeof(double));
166         memcpy(output_samples, buffer_samples, size * sizeof(double));
167
168         for(int i = size, j = 0; i < allocation; i++, j++)
169         {
170                 buffer_samples[j] = buffer_samples[i];
171         }
172
173         return 0;
174 }
175
176
177
178
179 void DelayAudio::update_gui()
180 {
181         if(thread)
182         {
183                 load_configuration();
184                 ((DelayAudioWindow*)thread->window)->lock_window();
185                 ((DelayAudioWindow*)thread->window)->update_gui();
186                 ((DelayAudioWindow*)thread->window)->unlock_window();
187         }
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 DelayAudioWindow::DelayAudioWindow(DelayAudio *plugin)
206  : PluginClientWindow(plugin, 
207         200, 
208         80, 
209         200, 
210         80, 
211         0)
212 {
213         this->plugin = plugin;
214 }
215
216 DelayAudioWindow::~DelayAudioWindow()
217 {
218 }
219
220 void DelayAudioWindow::create_objects()
221 {
222         add_subwindow(new BC_Title(10, 10, _("Delay seconds:")));
223         length = new DelayAudioTextBox(
224                 plugin, 
225                 this,
226                 10, 
227                 40);
228         length->create_objects();
229         update_gui();
230         show_window();
231 }
232
233 void DelayAudioWindow::update_gui()
234 {
235         char string[BCTEXTLEN];
236         sprintf(string, "%.04f", plugin->config.length);
237         length->update(string);
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251 DelayAudioTextBox::DelayAudioTextBox(
252         DelayAudio *plugin, 
253         DelayAudioWindow *window,
254         int x, 
255         int y)
256  : BC_TumbleTextBox(window,
257         (float)plugin->config.length,
258         (float)0,
259         (float)10,
260         x, 
261         y, 
262         100)
263 {
264         this->plugin = plugin;
265         set_increment(0.01);
266 }
267
268 DelayAudioTextBox::~DelayAudioTextBox()
269 {
270 }
271
272 int DelayAudioTextBox::handle_event()
273 {
274         plugin->config.length = atof(get_text());
275         if(plugin->config.length < 0) plugin->config.length = 0;
276         plugin->send_configure_change();
277         return 1;
278 }
279
280
281
282
283
284
285
286
287 DelayAudioConfig::DelayAudioConfig()
288 {
289         length = 1;
290 }
291         
292 int DelayAudioConfig::equivalent(DelayAudioConfig &that)
293 {
294         return(EQUIV(this->length, that.length));
295 }
296
297 void DelayAudioConfig::copy_from(DelayAudioConfig &that)
298 {
299         this->length = that.length;
300 }
301
302
303
304
305