00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003 #include "bchash.h"
00004 #include "delayaudio.h"
00005 #include "filexml.h"
00006 #include "picon_png.h"
00007 #include "vframe.h"
00008
00009 #include <string.h>
00010
00011 #include <libintl.h>
00012 #define _(String) gettext(String)
00013 #define gettext_noop(String) String
00014 #define N_(String) gettext_noop (String)
00015
00016
00017 PluginClient* new_plugin(PluginServer *server)
00018 {
00019 return new DelayAudio(server);
00020 }
00021
00022
00023 DelayAudio::DelayAudio(PluginServer *server)
00024 : PluginAClient(server)
00025 {
00026 reset();
00027 load_defaults();
00028 }
00029
00030 DelayAudio::~DelayAudio()
00031 {
00032 if(thread)
00033 {
00034 thread->window->set_done(0);
00035 thread->completion.lock();
00036 delete thread;
00037 }
00038
00039 save_defaults();
00040 delete defaults;
00041
00042 if(buffer) delete [] buffer;
00043 }
00044
00045
00046
00047 VFrame* DelayAudio::new_picon()
00048 {
00049 return new VFrame(picon_png);
00050 }
00051
00052 char* DelayAudio::plugin_title() { return N_("Delay audio"); }
00053 int DelayAudio::is_realtime() { return 1; }
00054
00055
00056 void DelayAudio::reset()
00057 {
00058 need_reconfigure = 1;
00059 buffer = 0;
00060 thread = 0;
00061 }
00062
00063 void DelayAudio::load_configuration()
00064 {
00065 KeyFrame *prev_keyframe;
00066 prev_keyframe = get_prev_keyframe(get_source_position());
00067
00068 DelayAudioConfig old_config;
00069 old_config.copy_from(config);
00070 read_data(prev_keyframe);
00071
00072 if(!old_config.equivalent(config))
00073 {
00074
00075 need_reconfigure = 1;
00076 }
00077 }
00078
00079 int DelayAudio::load_defaults()
00080 {
00081 char directory[BCTEXTLEN];
00082
00083 sprintf(directory, "%sdelayaudio.rc", BCASTDIR);
00084 defaults = new BC_Hash(directory);
00085 defaults->load();
00086 config.length = defaults->get("LENGTH", (double)1);
00087 return 0;
00088 }
00089
00090
00091
00092 int DelayAudio::save_defaults()
00093 {
00094 defaults->update("LENGTH", config.length);
00095 defaults->save();
00096 return 0;
00097 }
00098
00099 void DelayAudio::read_data(KeyFrame *keyframe)
00100 {
00101 FileXML input;
00102 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00103
00104 int result = 0;
00105 while(!result)
00106 {
00107 result = input.read_tag();
00108
00109 if(!result)
00110 {
00111 if(input.tag.title_is("DELAYAUDIO"))
00112 {
00113 config.length = input.tag.get_property("LENGTH", (double)config.length);
00114 }
00115 }
00116 }
00117 }
00118
00119
00120 void DelayAudio::save_data(KeyFrame *keyframe)
00121 {
00122 FileXML output;
00123 output.set_shared_string(keyframe->data, MESSAGESIZE);
00124
00125 output.tag.set_title("DELAYAUDIO");
00126 output.tag.set_property("LENGTH", (double)config.length);
00127 output.append_tag();
00128 output.tag.set_title("/DELAYAUDIO");
00129 output.append_tag();
00130 output.append_newline();
00131 output.terminate_string();
00132 }
00133
00134 void DelayAudio::reconfigure()
00135 {
00136 input_start = (int64_t)(config.length * PluginAClient::project_sample_rate + 0.5);
00137 int64_t new_allocation = input_start + PluginClient::in_buffer_size;
00138 double *new_buffer = new double[new_allocation];
00139 bzero(new_buffer, sizeof(double) * new_allocation);
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 if(buffer)
00150 {
00151 int size = MIN(new_allocation, allocation);
00152
00153 memcpy(new_buffer,
00154 buffer,
00155 (size - PluginClient::in_buffer_size) * sizeof(double));
00156 delete [] buffer;
00157 }
00158
00159 allocation = new_allocation;
00160 buffer = new_buffer;
00161 allocation = new_allocation;
00162 need_reconfigure = 0;
00163 }
00164
00165 int DelayAudio::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
00166 {
00167 load_configuration();
00168 if(need_reconfigure) reconfigure();
00169
00170
00171
00172
00173
00174
00175 memcpy(buffer + input_start, input_ptr, size * sizeof(double));
00176 memcpy(output_ptr, buffer, size * sizeof(double));
00177
00178 for(int i = size, j = 0; i < allocation; i++, j++)
00179 {
00180 buffer[j] = buffer[i];
00181 }
00182
00183 return 0;
00184 }
00185
00186 int DelayAudio::show_gui()
00187 {
00188 load_configuration();
00189
00190 thread = new DelayAudioThread(this);
00191 thread->start();
00192 return 0;
00193 }
00194
00195 int DelayAudio::set_string()
00196 {
00197 if(thread) thread->window->set_title(gui_string);
00198 return 0;
00199 }
00200
00201 void DelayAudio::raise_window()
00202 {
00203 if(thread)
00204 {
00205 thread->window->raise_window();
00206 thread->window->flush();
00207 }
00208 }
00209
00210 void DelayAudio::update_gui()
00211 {
00212 if(thread)
00213 {
00214 load_configuration();
00215 thread->window->lock_window();
00216 thread->window->update_gui();
00217 thread->window->unlock_window();
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 DelayAudioThread::DelayAudioThread(DelayAudio *plugin)
00233 : Thread()
00234 {
00235 this->plugin = plugin;
00236 set_synchronous(0);
00237 completion.lock();
00238 }
00239
00240
00241
00242
00243 DelayAudioThread::~DelayAudioThread()
00244 {
00245 delete window;
00246 }
00247
00248
00249 void DelayAudioThread::run()
00250 {
00251 BC_DisplayInfo info;
00252
00253 window = new DelayAudioWindow(plugin,
00254 info.get_abs_cursor_x() - 125,
00255 info.get_abs_cursor_y() - 115);
00256
00257 window->create_objects();
00258 int result = window->run_window();
00259 completion.unlock();
00260
00261 if(result) plugin->client_side_close();
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 DelayAudioWindow::DelayAudioWindow(DelayAudio *plugin, int x, int y)
00274 : BC_Window(plugin->gui_string,
00275 x,
00276 y,
00277 200,
00278 80,
00279 200,
00280 80,
00281 0,
00282 0,
00283 1)
00284 {
00285 this->plugin = plugin;
00286 }
00287
00288 DelayAudioWindow::~DelayAudioWindow()
00289 {
00290 }
00291
00292 int DelayAudioWindow::create_objects()
00293 {
00294 add_subwindow(new BC_Title(10, 10, _("Delay seconds:")));
00295 add_subwindow(length = new DelayAudioTextBox(plugin, 10, 40));
00296 update_gui();
00297 show_window();
00298 flush();
00299 return 0;
00300 }
00301
00302 int DelayAudioWindow::close_event()
00303 {
00304
00305 set_done(1);
00306 return 1;
00307 }
00308
00309 void DelayAudioWindow::update_gui()
00310 {
00311 char string[BCTEXTLEN];
00312 sprintf(string, "%.04f", plugin->config.length);
00313 length->update(string);
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 DelayAudioTextBox::DelayAudioTextBox(DelayAudio *plugin, int x, int y)
00328 : BC_TextBox(x, y, 150, 1, "")
00329 {
00330 this->plugin = plugin;
00331 }
00332
00333 DelayAudioTextBox::~DelayAudioTextBox()
00334 {
00335 }
00336
00337 int DelayAudioTextBox::handle_event()
00338 {
00339 plugin->config.length = atof(get_text());
00340 if(plugin->config.length < 0) plugin->config.length = 0;
00341 plugin->send_configure_change();
00342 return 1;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352 DelayAudioConfig::DelayAudioConfig()
00353 {
00354 length = 1;
00355 }
00356
00357 int DelayAudioConfig::equivalent(DelayAudioConfig &that)
00358 {
00359 return(EQUIV(this->length, that.length));
00360 }
00361
00362 void DelayAudioConfig::copy_from(DelayAudioConfig &that)
00363 {
00364 this->length = that.length;
00365 }
00366
00367
00368
00369
00370