00001 #include "bcdisplayinfo.h"
00002 #include "bchash.h"
00003 #include "filexml.h"
00004 #include "guicast.h"
00005 #include "language.h"
00006 #include "pluginaclient.h"
00007 #include "transportque.h"
00008
00009 #include <string.h>
00010
00011 class ReverseAudio;
00012
00013 class ReverseAudioConfig
00014 {
00015 public:
00016 ReverseAudioConfig();
00017 int enabled;
00018 };
00019
00020
00021 class ReverseAudioEnabled : public BC_CheckBox
00022 {
00023 public:
00024 ReverseAudioEnabled(ReverseAudio *plugin,
00025 int x,
00026 int y);
00027 int handle_event();
00028 ReverseAudio *plugin;
00029 };
00030
00031 class ReverseAudioWindow : public BC_Window
00032 {
00033 public:
00034 ReverseAudioWindow(ReverseAudio *plugin, int x, int y);
00035 ~ReverseAudioWindow();
00036 void create_objects();
00037 int close_event();
00038 ReverseAudio *plugin;
00039 ReverseAudioEnabled *enabled;
00040 };
00041
00042 PLUGIN_THREAD_HEADER(ReverseAudio, ReverseAudioThread, ReverseAudioWindow)
00043
00044 class ReverseAudio : public PluginAClient
00045 {
00046 public:
00047 ReverseAudio(PluginServer *server);
00048 ~ReverseAudio();
00049
00050 PLUGIN_CLASS_MEMBERS(ReverseAudioConfig, ReverseAudioThread)
00051
00052 int load_defaults();
00053 int save_defaults();
00054 void save_data(KeyFrame *keyframe);
00055 void read_data(KeyFrame *keyframe);
00056 void update_gui();
00057 int is_realtime();
00058 int process_buffer(int64_t size,
00059 double *buffer,
00060 int64_t start_position,
00061 int sample_rate);
00062
00063 int64_t input_position;
00064 int fragment_size;
00065 };
00066
00067
00068
00069
00070
00071
00072
00073 REGISTER_PLUGIN(ReverseAudio);
00074
00075
00076
00077 ReverseAudioConfig::ReverseAudioConfig()
00078 {
00079 enabled = 1;
00080 }
00081
00082
00083
00084
00085
00086 ReverseAudioWindow::ReverseAudioWindow(ReverseAudio *plugin, int x, int y)
00087 : BC_Window(plugin->gui_string,
00088 x,
00089 y,
00090 210,
00091 160,
00092 200,
00093 160,
00094 0,
00095 0,
00096 1)
00097 {
00098 this->plugin = plugin;
00099 }
00100
00101 ReverseAudioWindow::~ReverseAudioWindow()
00102 {
00103 }
00104
00105 void ReverseAudioWindow::create_objects()
00106 {
00107 int x = 10, y = 10;
00108
00109 add_subwindow(enabled = new ReverseAudioEnabled(plugin,
00110 x,
00111 y));
00112 show_window();
00113 flush();
00114 }
00115
00116 WINDOW_CLOSE_EVENT(ReverseAudioWindow)
00117
00118
00119 PLUGIN_THREAD_OBJECT(ReverseAudio, ReverseAudioThread, ReverseAudioWindow)
00120
00121
00122
00123
00124
00125
00126 ReverseAudioEnabled::ReverseAudioEnabled(ReverseAudio *plugin,
00127 int x,
00128 int y)
00129 : BC_CheckBox(x,
00130 y,
00131 plugin->config.enabled,
00132 _("Enabled"))
00133 {
00134 this->plugin = plugin;
00135 }
00136
00137 int ReverseAudioEnabled::handle_event()
00138 {
00139 plugin->config.enabled = get_value();
00140 plugin->send_configure_change();
00141 return 1;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 ReverseAudio::ReverseAudio(PluginServer *server)
00153 : PluginAClient(server)
00154 {
00155 PLUGIN_CONSTRUCTOR_MACRO
00156 }
00157
00158
00159 ReverseAudio::~ReverseAudio()
00160 {
00161 PLUGIN_DESTRUCTOR_MACRO
00162 }
00163
00164 char* ReverseAudio::plugin_title() { return N_("Reverse audio"); }
00165 int ReverseAudio::is_realtime() { return 1; }
00166
00167 #include "picon_png.h"
00168 NEW_PICON_MACRO(ReverseAudio)
00169
00170 SHOW_GUI_MACRO(ReverseAudio, ReverseAudioThread)
00171
00172 RAISE_WINDOW_MACRO(ReverseAudio)
00173
00174 SET_STRING_MACRO(ReverseAudio);
00175
00176
00177 int ReverseAudio::process_buffer(int64_t size,
00178 double *buffer,
00179 int64_t start_position,
00180 int sample_rate)
00181 {
00182 for(int i = 0; i < size; i += fragment_size)
00183 {
00184 fragment_size = size - i;
00185 load_configuration();
00186 if(config.enabled)
00187 {
00188 read_samples(buffer + i,
00189 0,
00190 sample_rate,
00191 input_position,
00192 fragment_size);
00193 for(int start = i, end = i + fragment_size - 1;
00194 end > start;
00195 start++, end--)
00196 {
00197 double temp = buffer[start];
00198 buffer[start] = buffer[end];
00199 buffer[end] = temp;
00200 }
00201 }
00202 else
00203 read_samples(buffer + i,
00204 0,
00205 sample_rate,
00206 start_position,
00207 fragment_size);
00208 if(get_direction() == PLAY_FORWARD)
00209 start_position += fragment_size;
00210 else
00211 start_position -= fragment_size;
00212 }
00213
00214
00215 return 0;
00216 }
00217
00218
00219
00220
00221 int ReverseAudio::load_configuration()
00222 {
00223 KeyFrame *prev_keyframe, *next_keyframe;
00224 next_keyframe = get_next_keyframe(get_source_position());
00225 prev_keyframe = get_prev_keyframe(get_source_position());
00226 read_data(next_keyframe);
00227
00228 read_data(prev_keyframe);
00229
00230 int64_t prev_position = edl_to_local(prev_keyframe->position);
00231 int64_t next_position = edl_to_local(next_keyframe->position);
00232
00233
00234
00235
00236
00237
00238
00239 if(prev_position == 0 && next_position == 0)
00240 {
00241 next_position = prev_position = get_source_start();
00242 }
00243
00244
00245 int64_t range_start = prev_position;
00246 int64_t range_end = next_position;
00247
00248
00249 if(range_start == range_end)
00250 {
00251
00252 if(get_source_position() >= get_source_start() &&
00253 get_source_position() < range_start)
00254 {
00255 range_start = get_source_start();
00256 }
00257 else
00258
00259 if(get_source_position() >= range_start &&
00260 get_source_position() < get_source_start() + get_total_len())
00261 {
00262 range_end = get_source_start() + get_total_len();
00263 }
00264 else
00265 {
00266
00267 ;
00268 }
00269 }
00270
00271
00272 if(get_direction() == PLAY_FORWARD)
00273 {
00274
00275 if(range_end - get_source_position() < fragment_size)
00276 fragment_size = range_end - get_source_position();
00277 input_position = get_source_position() - range_start;
00278 input_position = range_end - input_position - fragment_size;
00279 }
00280 else
00281 {
00282 if(get_source_position() - range_start < fragment_size)
00283 fragment_size = get_source_position() - range_start;
00284 input_position = range_end - get_source_position();
00285 input_position = range_start + input_position + fragment_size;
00286 }
00287
00288
00289
00290
00291
00292
00293 return 0;
00294 }
00295
00296 int ReverseAudio::load_defaults()
00297 {
00298 char directory[BCTEXTLEN];
00299
00300 sprintf(directory, "%sreverseaudio.rc", BCASTDIR);
00301
00302
00303 defaults = new BC_Hash(directory);
00304 defaults->load();
00305
00306 config.enabled = defaults->get("ENABLED", config.enabled);
00307 return 0;
00308 }
00309
00310 int ReverseAudio::save_defaults()
00311 {
00312 defaults->update("ENABLED", config.enabled);
00313 defaults->save();
00314 return 0;
00315 }
00316
00317 void ReverseAudio::save_data(KeyFrame *keyframe)
00318 {
00319 FileXML output;
00320
00321
00322 output.set_shared_string(keyframe->data, MESSAGESIZE);
00323 output.tag.set_title("REVERSEAUDIO");
00324 output.tag.set_property("ENABLED", config.enabled);
00325 output.append_tag();
00326 output.tag.set_title("/REVERSEAUDIO");
00327 output.append_tag();
00328 output.terminate_string();
00329 }
00330
00331 void ReverseAudio::read_data(KeyFrame *keyframe)
00332 {
00333 FileXML input;
00334
00335 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00336
00337 int result = 0;
00338
00339 while(!input.read_tag())
00340 {
00341 if(input.tag.title_is("REVERSEAUDIO"))
00342 {
00343 config.enabled = input.tag.get_property("ENABLED", config.enabled);
00344 }
00345 }
00346 }
00347
00348 void ReverseAudio::update_gui()
00349 {
00350 if(thread)
00351 {
00352 load_configuration();
00353 thread->window->lock_window();
00354 thread->window->enabled->update(config.enabled);
00355 thread->window->unlock_window();
00356 }
00357 }
00358
00359
00360
00361
00362