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