1 #include "bcdisplayinfo.h"
14 #define _(String) gettext(String)
15 #define gettext_noop(String) String
16 #define N_(String) gettext_noop (String)
21 #define WINDOW_BORDER (window_size / 2)
22 #define SGN(x) (x<0 ? -1: 1)
25 REGISTER_PLUGIN(DenoiseEffect)
31 DenoiseEffect::DenoiseEffect(PluginServer *server)
32 : PluginAClient(server)
35 PLUGIN_CONSTRUCTOR_MACRO
38 DenoiseEffect::~DenoiseEffect()
40 PLUGIN_DESTRUCTOR_MACRO
44 NEW_PICON_MACRO(DenoiseEffect)
46 LOAD_CONFIGURATION_MACRO(DenoiseEffect, DenoiseConfig)
48 SHOW_GUI_MACRO(DenoiseEffect, DenoiseThread)
50 RAISE_WINDOW_MACRO(DenoiseEffect)
52 SET_STRING_MACRO(DenoiseEffect)
54 void DenoiseEffect::delete_dsp()
56 if(ex_coeff_d) delete ex_coeff_d;
57 if(ex_coeff_r) delete ex_coeff_r;
58 if(ex_coeff_rn) delete ex_coeff_rn;
59 if(wave_coeff_d) delete wave_coeff_d;
60 if(wave_coeff_r) delete wave_coeff_r;
61 if(decomp_filter) delete decomp_filter;
62 if(recon_filter) delete recon_filter;
63 if(input_buffer) delete [] input_buffer;
64 if(output_buffer) delete [] output_buffer;
65 if(dsp_in) delete [] dsp_in;
66 if(dsp_out) delete [] dsp_out;
67 if(dsp_iteration) delete [] dsp_iteration;
84 void DenoiseEffect::reset()
100 output_allocation = 0;
117 char* DenoiseEffect::plugin_title()
123 int DenoiseEffect::is_realtime()
130 void DenoiseEffect::read_data(KeyFrame *keyframe)
133 input.set_shared_string(keyframe->data, strlen(keyframe->data));
138 result = input.read_tag();
142 if(input.tag.title_is("DENOISE"))
144 config.level = input.tag.get_property("LEVEL", config.level);
150 void DenoiseEffect::save_data(KeyFrame *keyframe)
153 output.set_shared_string(keyframe->data, MESSAGESIZE);
155 output.tag.set_title("DENOISE");
156 output.tag.set_property("LEVEL", config.level);
158 output.append_newline();
160 output.terminate_string();
163 int DenoiseEffect::load_defaults()
165 char directory[BCTEXTLEN], string[BCTEXTLEN];
166 sprintf(directory, "%sdenoise.rc", BCASTDIR);
167 defaults = new Defaults(directory);
170 config.level = defaults->get("LEVEL", config.level);
174 int DenoiseEffect::save_defaults()
176 char string[BCTEXTLEN];
178 defaults->update("LEVEL", config.level);
184 void DenoiseEffect::update_gui()
188 thread->window->lock_window();
189 thread->window->update();
190 thread->window->unlock_window();
196 double DenoiseEffect::dot_product(double *data, double *filter, char filtlen)
202 for(i = 0; i < filtlen; i++) sum += *data-- * *filter++;
206 int DenoiseEffect::convolve_dec_2(double *input_sequence,
210 double *output_sequence)
212 // convolve the input sequence with the filter and decimate by two
213 int i, shortlen, offset;
214 int64_t lengthp4 = length + 4;
215 int64_t lengthm4 = length - 4;
216 int64_t lengthp5 = length + 5;
217 int64_t lengthp8 = length + 8;
219 for(i = 0; (i <= lengthp8) && ((i - filtlen) <= lengthp8); i += 2)
222 *output_sequence++ = dot_product(input_sequence + i, filter, i + 1);
226 offset = i - lengthm4;
227 shortlen = filtlen - offset;
228 *output_sequence++ = dot_product(input_sequence + lengthp4,
229 filter + offset, shortlen);
232 *output_sequence++ = dot_product(input_sequence + i, filter, filtlen);
237 int64_t DenoiseEffect::decompose_branches(double *in_data,
239 WaveletFilters *decomp_filter,
243 // Take input data and filters and form two branches of half the
244 // original length. Length of branches is returned.
245 convolve_dec_2(in_data, length, decomp_filter->h, decomp_filter->length, out_low);
246 convolve_dec_2(in_data, length, decomp_filter->g, decomp_filter->length, out_high);
250 int DenoiseEffect::wavelet_decomposition(double *in_data,
254 for(int i = 0; i < levels; i++)
256 in_length = decompose_branches(in_data,
260 out_data[(2 * i) + 1]);
262 in_data = out_data[2 * i];
267 int DenoiseEffect::tree_copy(double **output,
272 register int i, j, k, l, m;
274 for(i = 0, k = 1; k < levels; i++, k++)
280 for(j = 0; j < length + 5; j++)
283 output[m][j] = input[m][j];
291 for(j = 0; j < length + 5; j++)
293 output[l][j] = input[l][j];
294 output[m][j] = input[m][j];
299 int DenoiseEffect::threshold(int window_size, double gammas, int levels)
302 double threshold, cv, cvb, abs_coeff_r;
303 double *coeff_r, *coeff_l;
306 for(i = 0; i < levels; i++)
308 length = (window_size >> (i + 1)) + 5;
309 threshold = sqrt(2 * log(length) / log(2)) * gammas / sqrt(length);
311 for(j = 0; j < length; j++)
313 coeff_r = &(ex_coeff_r->values[(2 * i) + 1][j]);
314 coeff_l = &(ex_coeff_rn->values[(2 * i) + 1][j]);
317 abs_coeff_r = fabs(*coeff_r);
318 cvb = abs_coeff_r - threshold;
321 if(abs_coeff_r > threshold)
336 double DenoiseEffect::dot_product_even(double *data, double *filter, int filtlen)
342 for(i = 0; i < filtlen; i += 2) sum += *data-- * filter[i];
347 double DenoiseEffect::dot_product_odd(double *data, double *filter, int filtlen)
353 for(i = 1; i < filtlen; i += 2) sum += *data-- * filter[i];
357 int DenoiseEffect::convolve_int_2(double *input_sequence,
362 double *output_sequence)
363 // insert zeros between each element of the input sequence and
364 // convolve with the filter to interpolate the data
367 int endpoint = length + filtlen - 2;
371 // summation with previous convolution
372 // every other dot product interpolates the data
373 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
375 *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
376 *output_sequence++ += dot_product_even(input_sequence + j, filter, filtlen);
379 *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
383 // first convolution of pair
384 // every other dot product interpolates the data
385 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
387 *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
388 *output_sequence++ = dot_product_even(input_sequence + j, filter, filtlen);
391 *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
397 int64_t DenoiseEffect::reconstruct_branches(double *in_low,
400 WaveletFilters *recon_filter,
403 // take input data and filters and form two branches of half the
404 // original length. length of branches is returned
405 convolve_int_2(in_low, in_length, recon_filter->h,
406 recon_filter->length, 0, output);
407 convolve_int_2(in_high, in_length, recon_filter->g,
408 recon_filter->length, 1, output);
409 return in_length * 2;
412 int DenoiseEffect::wavelet_reconstruction(double **in_data,
419 in_length = in_length >> levels;
420 // destination of all but last branch reconstruction is the next
421 // higher intermediate approximation
422 for(i = levels - 1; i > 0; i--)
424 output = in_data[2 * (i - 1)];
425 in_length = reconstruct_branches(in_data[2 * i],
426 in_data[(2 * i) + 1],
432 // destination of the last branch reconstruction is the output data
433 reconstruct_branches(in_data[0],
442 void DenoiseEffect::process_window()
445 for(j = 0; j < iterations; j++)
447 wavelet_decomposition(dsp_in, window_size, ex_coeff_d->values);
449 tree_copy(ex_coeff_r->values, ex_coeff_d->values, window_size, levels);
450 tree_copy(ex_coeff_rn->values, ex_coeff_d->values, window_size, levels);
453 //printf("DenoiseEffect::process_window %f\n", config.level);
454 threshold(window_size, config.level * 10.0, levels);
456 wavelet_reconstruction(ex_coeff_r->values, window_size, dsp_iteration);
457 wavelet_reconstruction(ex_coeff_rn->values, window_size, dsp_in);
459 for(i = 0; i < window_size; i++)
460 dsp_out[i] += dsp_iteration[i];
467 int DenoiseEffect::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
469 load_configuration();
473 int64_t size_factor = (int)(pow(2, levels));
474 dsp_in = new double[window_size * size_factor];
475 dsp_out = new double[window_size * 2];
476 dsp_iteration = new double[window_size * 2];
479 ex_coeff_d = new Tree(window_size, levels);
480 ex_coeff_r = new Tree(window_size, levels);
481 ex_coeff_rn = new Tree(window_size, levels);
482 wave_coeff_d = new WaveletCoeffs(alpha, beta);
483 wave_coeff_r = new WaveletCoeffs(alpha, beta);
484 decomp_filter = new WaveletFilters(wave_coeff_d, DECOMP);
485 recon_filter = new WaveletFilters(wave_coeff_r, RECON);
486 in_scale = 65535 / sqrt(window_size) / iterations;
487 out_scale = output_level / 65535 * sqrt(window_size);
491 // Append input buffer
492 if(input_size + size > input_allocation)
494 double *new_input = new double[input_size + size];
497 memcpy(new_input, input_buffer, sizeof(double) * input_size);
498 delete [] input_buffer;
500 input_buffer = new_input;
501 input_allocation = input_size + size;
503 memcpy(input_buffer + input_size,
505 size * sizeof(double));
509 // Have enough to do some windows
510 while(input_size >= window_size)
513 for(int i = 0; i < window_size; i++)
515 dsp_in[i] = input_buffer[i] * in_scale;
517 bzero(dsp_out, sizeof(double) * window_size);
524 // First window produces garbage
534 // Crossfade into the output buffer
535 int64_t new_allocation = output_size + window_size;
536 if(new_allocation > output_allocation)
538 double *new_output = new double[new_allocation];
542 memcpy(new_output, output_buffer, sizeof(double) * output_size);
543 //printf("CrossfadeFFT::process_fifo 1 %p\n", output_buffer);
544 delete [] output_buffer;
545 //printf("CrossfadeFFT::process_fifo 2\n");
547 output_buffer = new_output;
548 output_allocation = new_allocation;
551 if(output_size >= WINDOW_BORDER)
553 for(int i = 0, j = output_size - WINDOW_BORDER;
557 double src_level = (double)i / WINDOW_BORDER;
558 double dst_level = (double)(WINDOW_BORDER - i) / WINDOW_BORDER;
559 output_buffer[j] = output_buffer[j] * dst_level + out_scale * dsp_out[i] * src_level;
562 for(int i = 0; i < window_size - WINDOW_BORDER; i++)
563 output_buffer[output_size + i] = dsp_out[WINDOW_BORDER + i] * out_scale;
564 output_size += window_size - WINDOW_BORDER;
568 // First buffer has no crossfade
569 memcpy(output_buffer + output_size,
571 sizeof(double) * window_size);
572 output_size += window_size;
576 // Shift input buffer forward
577 for(int i = window_size - WINDOW_BORDER, j = 0;
580 input_buffer[j] = input_buffer[i];
581 input_size -= window_size - WINDOW_BORDER;
585 // Have enough to send to output
586 if(output_size - WINDOW_BORDER >= size)
588 memcpy(output_ptr, output_buffer, sizeof(double) * size);
589 for(int i = size, j = 0; i < output_size; i++, j++)
590 output_buffer[j] = output_buffer[i];
595 //printf("DenoiseEffect::process_realtime 1\n");
596 bzero(output_ptr, sizeof(double) * size);
608 Tree::Tree(int input_length, int levels)
610 this->input_length = input_length;
611 this->levels = levels;
614 // create decomposition tree
615 values = new double*[2 * levels];
617 for (i = 0; i < levels; i++)
625 values[2 * i] = new double[j + 5];
626 values[2 * i + 1] = new double[j + 5];
634 for (i = 2 * levels - 1; i >= 0; i--)
640 WaveletCoeffs::WaveletCoeffs(double alpha, double beta)
643 double tcosa = cos(alpha);
644 double tcosb = cos(beta);
645 double tsina = sin(alpha);
646 double tsinb = sin(beta);
648 // calculate first two wavelet coefficients a = a(-2) and b = a(-1)
649 values[0] = ((1.0 + tcosa + tsina) * (1.0 - tcosb - tsinb)
650 + 2.0 * tsinb * tcosa) / 4.0;
651 values[1] = ((1.0 - tcosa + tsina) * (1.0 + tcosb - tsinb)
652 - 2.0 * tsinb * tcosa) / 4.0;
654 tcosa = cos(alpha - beta);
655 tsina = sin(alpha - beta);
657 // calculate last four wavelet coefficients c = a(0), d = a(1),
658 // e = a(2), and f = a(3)
659 values[2] = (1.0 + tcosa + tsina) / 2.0;
660 values[3] = (1.0 + tcosa - tsina) / 2.0;
661 values[4] = 1 - values[0] - values[2];
662 values[5] = 1 - values[1] - values[3];
664 // zero out very small coefficient values caused by truncation error
665 for (i = 0; i < 6; i++)
667 if (fabs(values[i]) < 1.0e-15) values[i] = 0.0;
671 WaveletCoeffs::~WaveletCoeffs()
676 WaveletFilters::WaveletFilters(WaveletCoeffs *wave_coeffs, wavetype transform)
680 // find the first non-zero wavelet coefficient
682 while(wave_coeffs->values[i] == 0.0) i++;
684 // find the last non-zero wavelet coefficient
686 while(wave_coeffs->values[j] == 0.0) j--;
688 // Form the decomposition filters h~ and g~ or the reconstruction
689 // filters h and g. The division by 2 in the construction
690 // of the decomposition filters is for normalization.
692 for(k = 0; k < length; k++)
694 if (transform == DECOMP)
696 h[k] = wave_coeffs->values[j--] / 2.0;
697 g[k] = (double) (((i++ & 0x01) * 2) - 1) * wave_coeffs->values[i] / 2.0;
701 h[k] = wave_coeffs->values[i++];
702 g[k] = (double) (((j-- & 0x01) * 2) - 1) * wave_coeffs->values[j];
706 // clear out the additional array locations, if any
714 WaveletFilters::~WaveletFilters()
726 DenoiseConfig::DenoiseConfig()
731 void DenoiseConfig::copy_from(DenoiseConfig &that)
736 int DenoiseConfig::equivalent(DenoiseConfig &that)
738 return EQUIV(level, that.level);
741 void DenoiseConfig::interpolate(DenoiseConfig &prev,
745 int64_t current_frame)
747 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
748 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
749 this->level = prev.level * prev_scale + next.level * next_scale;
761 PLUGIN_THREAD_OBJECT(DenoiseEffect, DenoiseThread, DenoiseWindow)
772 DenoiseWindow::DenoiseWindow(DenoiseEffect *plugin, int x, int y)
773 : BC_Window(plugin->gui_string,
784 this->plugin = plugin;
787 void DenoiseWindow::create_objects()
791 add_subwindow(new BC_Title(x, y, _("Level:")));
793 add_subwindow(scale = new DenoiseLevel(plugin, x, y));
798 int DenoiseWindow::close_event()
800 // Set result to 1 to indicate a client side close
805 void DenoiseWindow::update()
807 scale->update(plugin->config.level);
821 DenoiseLevel::DenoiseLevel(DenoiseEffect *plugin, int x, int y)
822 : BC_FPot(x, y, (float)plugin->config.level, 0, 1.0)
824 this->plugin = plugin;
828 int DenoiseLevel::handle_event()
830 plugin->config.level = get_value();
831 plugin->send_configure_change();