vicon drawing segv fix, beeper consolidation, render_effect resize wdw fix, valgrind...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / denoise / denoise.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 "filexml.h"
26 #include "denoise.h"
27 #include "language.h"
28 #include "samples.h"
29 #include "units.h"
30 #include "vframe.h"
31
32 #include <math.h>
33 #include <string.h>
34
35
36
37
38 #define WINDOW_BORDER (window_size / 2)
39 #define SGN(x) (x<0 ? -1: 1)
40
41
42 REGISTER_PLUGIN(DenoiseEffect)
43
44
45
46
47
48 DenoiseEffect::DenoiseEffect(PluginServer *server)
49  : PluginAClient(server)
50 {
51         reset();
52
53 }
54
55 DenoiseEffect::~DenoiseEffect()
56 {
57
58         delete_dsp();
59 }
60
61
62 LOAD_CONFIGURATION_MACRO(DenoiseEffect, DenoiseConfig)
63
64 NEW_WINDOW_MACRO(DenoiseEffect, DenoiseWindow)
65
66 void DenoiseEffect::delete_dsp()
67 {
68         if(ex_coeff_d) delete ex_coeff_d;
69         if(ex_coeff_r) delete ex_coeff_r;
70         if(ex_coeff_rn) delete ex_coeff_rn;
71         if(wave_coeff_d) delete wave_coeff_d;
72         if(wave_coeff_r) delete wave_coeff_r;
73         if(decomp_filter) delete decomp_filter;
74         if(recon_filter) delete recon_filter;
75         if(input_buffer) delete [] input_buffer;
76         if(output_buffer) delete [] output_buffer;
77         if(dsp_in) delete [] dsp_in;
78         if(dsp_out) delete [] dsp_out;
79         if(dsp_iteration) delete [] dsp_iteration;
80
81         ex_coeff_d = 0;
82         ex_coeff_r = 0;
83         ex_coeff_rn = 0;
84         wave_coeff_d = 0;
85         wave_coeff_r = 0;
86         decomp_filter = 0;
87         recon_filter = 0;
88         input_buffer = 0;
89         output_buffer = 0;
90         dsp_in = 0;
91         dsp_out = 0;
92         dsp_iteration = 0;
93 }
94
95
96 void DenoiseEffect::reset()
97 {
98         first_window = 1;
99         thread = 0;
100         ex_coeff_d = 0;
101         ex_coeff_r = 0;
102         ex_coeff_rn = 0;
103         wave_coeff_d = 0;
104         wave_coeff_r = 0;
105         decomp_filter = 0;
106         recon_filter = 0;
107         input_buffer = 0;
108         output_buffer = 0;
109         input_size = 0;
110         output_size = 0;
111         input_allocation = 0;
112         output_allocation = 0;
113         dsp_iteration = 0;
114         in_scale = 0;
115         out_scale = 0;
116         dsp_in = 0;
117         dsp_out = 0;
118         initialized = 0;
119
120
121         alpha = 1.359803732;
122         beta = -0.782106385;
123         window_size = 4096;
124         output_level = 1.0;
125         levels = 1;
126         iterations = 1;
127 }
128
129 const char* DenoiseEffect::plugin_title() { return N_("Denoise"); }
130 int DenoiseEffect::is_realtime() { return 1; }
131
132
133
134 void DenoiseEffect::read_data(KeyFrame *keyframe)
135 {
136         FileXML input;
137         input.set_shared_input(keyframe->xbuf);
138
139         int result = 0;
140         while(!result)
141         {
142                 result = input.read_tag();
143
144                 if(!result)
145                 {
146                         if(input.tag.title_is("DENOISE"))
147                         {
148                                 config.level = input.tag.get_property("LEVEL", config.level);
149                         }
150                 }
151         }
152 }
153
154 void DenoiseEffect::save_data(KeyFrame *keyframe)
155 {
156         FileXML output;
157         output.set_shared_output(keyframe->xbuf);
158
159         output.tag.set_title("DENOISE");
160         output.tag.set_property("LEVEL", config.level);
161         output.append_tag();
162         output.tag.set_title("/DENOISE");
163         output.append_tag();
164         output.append_newline();
165         output.terminate_string();
166 }
167
168
169 void DenoiseEffect::update_gui()
170 {
171         if(thread)
172         {
173                 ((DenoiseWindow*)thread->window)->lock_window();
174                 ((DenoiseWindow*)thread->window)->update();
175                 ((DenoiseWindow*)thread->window)->unlock_window();
176         }
177 }
178
179
180
181 double DenoiseEffect::dot_product(double *data, double *filter, char filtlen)
182 {
183         static int i;
184         static double sum;
185
186         sum = 0.0;
187         for(i = 0; i < filtlen; i++) sum += *data-- * *filter++;
188         return sum;
189 }
190
191 int DenoiseEffect::convolve_dec_2(double *input_sequence,
192         int64_t length,
193         double *filter,
194         int filtlen,
195         double *output_sequence)
196 {
197 // convolve the input sequence with the filter and decimate by two
198         int i, shortlen, offset;
199         int64_t lengthp4 = length + 4;
200         int64_t lengthm4 = length - 4;
201         int64_t lengthp5 = length + 5;
202         int64_t lengthp8 = length + 8;
203
204         for(i = 0; (i <= lengthp8) && ((i - filtlen) <= lengthp8); i += 2)
205         {
206                 if(i < filtlen)
207                         *output_sequence++ = dot_product(input_sequence + i, filter, i + 1);
208                 else
209                 if(i > lengthp5)
210                 {
211                         offset = i - lengthm4;
212                         shortlen = filtlen - offset;
213                         *output_sequence++ = dot_product(input_sequence + lengthp4,
214                                                                 filter + offset, shortlen);
215                 }
216                 else
217                         *output_sequence++ = dot_product(input_sequence + i, filter, filtlen);
218         }
219         return 0;
220 }
221
222 int64_t DenoiseEffect::decompose_branches(double *in_data,
223         int64_t length,
224         WaveletFilters *decomp_filter,
225         double *out_low,
226         double *out_high)
227 {
228 // Take input data and filters and form two branches of half the
229 // original length. Length of branches is returned.
230         convolve_dec_2(in_data, length, decomp_filter->h, decomp_filter->length, out_low);
231         convolve_dec_2(in_data, length, decomp_filter->g, decomp_filter->length, out_high);
232         return (length / 2);
233 }
234
235 int DenoiseEffect::wavelet_decomposition(double *in_data,
236         int64_t in_length,
237         double **out_data)
238 {
239         for(int i = 0; i < levels; i++)
240         {
241                 in_length = decompose_branches(in_data,
242                         in_length,
243                         decomp_filter,
244                         out_data[2 * i],
245                         out_data[(2 * i) + 1]);
246
247                 in_data = out_data[2 * i];
248         }
249         return 0;
250 }
251
252 int DenoiseEffect::tree_copy(double **output,
253         double **input,
254         int length,
255         int levels)
256 {
257         int i, j, k, l, m;
258
259         for(i = 0, k = 1; k < levels; i++, k++)
260         {
261                 length /= 2;
262                 l = 2 * i;
263                 m = l + 1;
264
265                 for(j = 0; j < length + 5; j++)
266                 {
267                         output[l][j] = 0.0;
268                         output[m][j] = input[m][j];
269                 }
270         }
271
272         length /= 2;
273         l = 2 * i;
274         m = l + 1;
275
276         for(j = 0; j < length + 5; j++)
277         {
278                 output[l][j] = input[l][j];
279                 output[m][j] = input[m][j];
280         }
281         return 0;
282 }
283
284 int DenoiseEffect::threshold(int window_size, double gammas, int levels)
285 {
286         int i, j;
287         double threshold, cv, cvb, abs_coeff_r;
288         double *coeff_r, *coeff_l;
289         int length;
290
291         for(i = 0; i < levels; i++)
292         {
293                 length = (window_size >> (i + 1)) + 5;
294                 threshold = sqrt(2 * log(length) / log(2)) * gammas / sqrt(length);
295
296                 for(j = 0; j < length; j++)
297                 {
298                         coeff_r = &(ex_coeff_r->values[(2 * i) + 1][j]);
299                         coeff_l = &(ex_coeff_rn->values[(2 * i) + 1][j]);
300
301                         cv = SGN(*coeff_r);
302                         abs_coeff_r = fabs(*coeff_r);
303                         cvb = abs_coeff_r - threshold;
304                         cv *= cvb;
305
306                         if(abs_coeff_r > threshold)
307                         {
308                                 *coeff_r = cv;
309                                 *coeff_l = 0.0;
310                         }
311                         else
312                         {
313                                 *coeff_l = *coeff_r;
314                                 *coeff_r = 0.0;
315                         }
316                 }
317         }
318         return 0;
319 }
320
321
322 double DenoiseEffect::dot_product_even(double *data, double *filter, int filtlen)
323 {
324         static int i;
325         static double sum;
326
327         sum = 0.0;
328         for(i = 0; i < filtlen; i += 2) sum += *data-- * filter[i];
329         return sum;
330 }
331
332
333 double DenoiseEffect::dot_product_odd(double *data, double *filter, int filtlen)
334 {
335         static int i;
336         static double sum;
337
338         sum = 0.0;
339         for(i = 1; i < filtlen; i += 2) sum += *data-- * filter[i];
340         return sum;
341 }
342
343 int DenoiseEffect::convolve_int_2(double *input_sequence,
344         int64_t length,
345         double *filter,
346         int filtlen,
347         int sum_output,
348         double *output_sequence)
349 // insert zeros between each element of the input sequence and
350 // convolve with the filter to interpolate the data
351 {
352         int i, j;
353         int endpoint = length + filtlen - 2;
354
355         if (sum_output)
356         {
357 // summation with previous convolution
358 // every other dot product interpolates the data
359                 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
360                 {
361                         *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
362                         *output_sequence++ += dot_product_even(input_sequence + j, filter, filtlen);
363                 }
364
365                 *output_sequence++ += dot_product_odd(input_sequence + i, filter, filtlen);
366         }
367         else
368         {
369 // first convolution of pair
370 // every other dot product interpolates the data
371                 for(i = (filtlen / 2) - 1, j = (filtlen / 2); i < endpoint; i++, j++)
372                 {
373                         *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
374                         *output_sequence++ = dot_product_even(input_sequence + j, filter, filtlen);
375                 }
376
377                 *output_sequence++ = dot_product_odd(input_sequence + i, filter, filtlen);
378         }
379         return 0;
380 }
381
382
383 int64_t DenoiseEffect::reconstruct_branches(double *in_low,
384         double *in_high,
385         int64_t in_length,
386         WaveletFilters *recon_filter,
387         double *output)
388 {
389 // take input data and filters and form two branches of half the
390 // original length. length of branches is returned
391         convolve_int_2(in_low, in_length, recon_filter->h,
392                                         recon_filter->length, 0, output);
393         convolve_int_2(in_high, in_length, recon_filter->g,
394                                         recon_filter->length, 1, output);
395         return in_length * 2;
396 }
397
398 int DenoiseEffect::wavelet_reconstruction(double **in_data,
399         int64_t in_length,
400         double *out_data)
401 {
402         double *output;
403         int i;
404
405         in_length = in_length >> levels;
406 // destination of all but last branch reconstruction is the next
407 // higher intermediate approximation
408         for(i = levels - 1; i > 0; i--)
409         {
410                 output = in_data[2 * (i - 1)];
411                 in_length = reconstruct_branches(in_data[2 * i],
412                         in_data[(2 * i) + 1],
413                         in_length,
414                         recon_filter,
415                         output);
416         }
417
418 // destination of the last branch reconstruction is the output data
419         reconstruct_branches(in_data[0],
420                 in_data[1],
421                 in_length,
422                 recon_filter,
423                 out_data);
424
425         return 0;
426 }
427
428 void DenoiseEffect::process_window()
429 {
430         int i, j;
431         for(j = 0; j < iterations; j++)
432         {
433                 wavelet_decomposition(dsp_in, window_size, ex_coeff_d->values);
434
435                 tree_copy(ex_coeff_r->values, ex_coeff_d->values, window_size, levels);
436                 tree_copy(ex_coeff_rn->values, ex_coeff_d->values, window_size, levels);
437
438 // qualify coeffs
439 //printf("DenoiseEffect::process_window %f\n", config.level);
440                 threshold(window_size, config.level * 10.0, levels);
441
442                 wavelet_reconstruction(ex_coeff_r->values, window_size, dsp_iteration);
443                 wavelet_reconstruction(ex_coeff_rn->values, window_size, dsp_in);
444
445                 for(i = 0; i < window_size; i++)
446                         dsp_out[i] += dsp_iteration[i];
447         }
448 }
449
450
451
452
453 int DenoiseEffect::process_realtime(int64_t size, Samples *input_ptr, Samples *output_ptr)
454 {
455         load_configuration();
456
457         if(!initialized)
458         {
459                 int64_t size_factor = (int)(pow(2, levels));
460                 dsp_in = new double[window_size * size_factor];
461                 dsp_out = new double[window_size * 2];
462                 dsp_iteration = new double[window_size * 2];
463
464
465                 ex_coeff_d = new Tree(window_size, levels);
466                 ex_coeff_r = new Tree(window_size, levels);
467                 ex_coeff_rn = new Tree(window_size, levels);
468                 wave_coeff_d = new WaveletCoeffs(alpha, beta);
469                 wave_coeff_r = new WaveletCoeffs(alpha, beta);
470                 decomp_filter = new WaveletFilters(wave_coeff_d, DECOMP);
471                 recon_filter = new WaveletFilters(wave_coeff_r, RECON);
472                 in_scale = 65535 / sqrt(window_size) / iterations;
473                 out_scale = output_level / 65535 * sqrt(window_size);
474                 initialized = 1;
475         }
476
477 // Append input buffer
478         if(input_size + size > input_allocation)
479         {
480                 double *new_input = new double[input_size + size];
481                 if(input_buffer)
482                 {
483                         memcpy(new_input, input_buffer, sizeof(double) * input_size);
484                         delete [] input_buffer;
485                 }
486                 input_buffer = new_input;
487                 input_allocation = input_size + size;
488         }
489         memcpy(input_buffer + input_size,
490                 input_ptr->get_data(),
491                 size * sizeof(double));
492         input_size += size;
493
494
495 // Have enough to do some windows
496         while(input_size >= window_size)
497         {
498 // Load dsp_in
499                 for(int i = 0; i < window_size; i++)
500                 {
501                         dsp_in[i] = input_buffer[i] * in_scale;
502                 }
503                 bzero(dsp_out, sizeof(double) * window_size);
504
505
506
507
508
509
510 // First window produces garbage
511                 if(!first_window)
512                         process_window();
513                 first_window = 0;
514
515
516
517
518
519
520 // Crossfade into the output buffer
521                 int64_t new_allocation = output_size + window_size;
522                 if(new_allocation > output_allocation)
523                 {
524                         double *new_output = new double[new_allocation];
525
526                         if(output_buffer)
527                         {
528                                 memcpy(new_output, output_buffer, sizeof(double) * output_size);
529 //printf("CrossfadeFFT::process_fifo 1 %p\n", output_buffer);
530                                 delete [] output_buffer;
531 //printf("CrossfadeFFT::process_fifo 2\n");
532                         }
533                         output_buffer = new_output;
534                         output_allocation = new_allocation;
535                 }
536
537                 if(output_size >= WINDOW_BORDER)
538                 {
539                         for(int i = 0, j = output_size - WINDOW_BORDER;
540                                 i < WINDOW_BORDER;
541                                 i++, j++)
542                         {
543                                 double src_level = (double)i / WINDOW_BORDER;
544                                 double dst_level = (double)(WINDOW_BORDER - i) / WINDOW_BORDER;
545                                 output_buffer[j] = output_buffer[j] * dst_level + out_scale * dsp_out[i] * src_level;
546                         }
547
548                         for(int i = 0; i < window_size - WINDOW_BORDER; i++)
549                                 output_buffer[output_size + i] = dsp_out[WINDOW_BORDER + i] * out_scale;
550                         output_size += window_size - WINDOW_BORDER;
551                 }
552                 else
553                 {
554 // First buffer has no crossfade
555                         memcpy(output_buffer + output_size,
556                                 dsp_out,
557                                 sizeof(double) * window_size);
558                         output_size += window_size;
559                 }
560
561
562 // Shift input buffer forward
563                 for(int i = window_size - WINDOW_BORDER, j = 0;
564                         i < input_size;
565                         i++, j++)
566                         input_buffer[j] = input_buffer[i];
567                 input_size -= window_size - WINDOW_BORDER;
568         }
569
570
571 // Have enough to send to output
572         if(output_size - WINDOW_BORDER >= size)
573         {
574                 memcpy(output_ptr->get_data(), output_buffer, sizeof(double) * size);
575                 for(int i = size, j = 0; i < output_size; i++, j++)
576                         output_buffer[j] = output_buffer[i];
577                 output_size -= size;
578         }
579         else
580         {
581 //printf("DenoiseEffect::process_realtime 1\n");
582                 bzero(output_ptr->get_data(), sizeof(double) * size);
583         }
584
585         return 0;
586 }
587
588
589
590
591
592
593
594 Tree::Tree(int input_length, int levels)
595 {
596         this->input_length = input_length;
597         this->levels = levels;
598         int i, j;
599
600 // create decomposition tree
601         values = new double*[2 * levels];
602         j = input_length;
603         for (i = 0; i < levels; i++)
604         {
605                 j /= 2;
606                 if (j == 0)
607                 {
608                         levels = i;
609                         continue;
610                 }
611                 values[2 * i] = new double[j + 5];
612                 values[2 * i + 1] = new double[j + 5];
613         }
614 }
615
616 Tree::~Tree()
617 {
618         int i;
619
620         for (i = 2 * levels - 1; i >= 0; i--)
621                 delete [] values[i];
622
623         delete values;
624 }
625
626 WaveletCoeffs::WaveletCoeffs(double alpha, double beta)
627 {
628         int i;
629         double tcosa = cos(alpha);
630         double tcosb = cos(beta);
631         double tsina = sin(alpha);
632         double tsinb = sin(beta);
633
634 // calculate first two wavelet coefficients  a = a(-2) and b = a(-1)
635         values[0] = ((1.0 + tcosa + tsina) * (1.0 - tcosb - tsinb)
636                                         + 2.0 * tsinb * tcosa) / 4.0;
637         values[1] = ((1.0 - tcosa + tsina) * (1.0 + tcosb - tsinb)
638                                         - 2.0 * tsinb * tcosa) / 4.0;
639
640         tcosa = cos(alpha - beta);
641         tsina = sin(alpha - beta);
642
643 // calculate last four wavelet coefficients  c = a(0), d = a(1),
644 // e = a(2), and f = a(3)
645         values[2]  = (1.0 + tcosa + tsina) / 2.0;
646         values[3]  = (1.0 + tcosa - tsina) / 2.0;
647         values[4]  = 1 - values[0] - values[2];
648         values[5]  = 1 - values[1] - values[3];
649
650 // zero out very small coefficient values caused by truncation error
651         for (i = 0; i < 6; i++)
652         {
653                 if (fabs(values[i]) < 1.0e-15) values[i] = 0.0;
654         }
655 }
656
657 WaveletCoeffs::~WaveletCoeffs()
658 {
659 }
660
661
662 WaveletFilters::WaveletFilters(WaveletCoeffs *wave_coeffs, wavetype transform)
663 {
664         int i, j, k;
665
666 // find the first non-zero wavelet coefficient
667         i = 0;
668         while(wave_coeffs->values[i] == 0.0) i++;
669
670 // find the last non-zero wavelet coefficient
671         j = 5;
672         while(wave_coeffs->values[j] == 0.0) j--;
673
674 // Form the decomposition filters h~ and g~ or the reconstruction
675 // filters h and g.  The division by 2 in the construction
676 // of the decomposition filters is for normalization.
677         length = j - i + 1;
678         for(k = 0; k < length; ++i, --j, ++k)
679         {
680                 if (transform == DECOMP)
681                 {
682                         h[k] = wave_coeffs->values[j] / 2.0;
683                         g[k] = (double) (((i & 0x01) * 2) - 1) * wave_coeffs->values[i] / 2.0;
684                 }
685                 else
686                 {
687                         h[k] = wave_coeffs->values[i];
688                         g[k] = (double) (((j & 0x01) * 2) - 1) * wave_coeffs->values[j];
689                 }
690         }
691
692 // clear out the additional array locations, if any
693         while (k < 6)
694         {
695                 h[k] = g[k] = 0.0;
696                 ++k;
697         }
698 }
699
700 WaveletFilters::~WaveletFilters()
701 {
702 }
703
704
705
706
707
708
709
710
711
712 DenoiseConfig::DenoiseConfig()
713 {
714         level = 1.0;
715 }
716
717 void DenoiseConfig::copy_from(DenoiseConfig &that)
718 {
719         level = that.level;
720 }
721
722 int DenoiseConfig::equivalent(DenoiseConfig &that)
723 {
724         return EQUIV(level, that.level);
725 }
726
727 void DenoiseConfig::interpolate(DenoiseConfig &prev,
728         DenoiseConfig &next,
729         int64_t prev_frame,
730         int64_t next_frame,
731         int64_t current_frame)
732 {
733         double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
734         double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
735         this->level = prev.level * prev_scale + next.level * next_scale;
736 }
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756 DenoiseWindow::DenoiseWindow(DenoiseEffect *plugin)
757  : PluginClientWindow(plugin, xS(200), yS(60), xS(200), yS(60), 0)
758 {
759         this->plugin = plugin;
760 }
761
762 void DenoiseWindow::create_objects()
763 {
764         int xs10 = xS(10), xs70 = xS(70);
765         int ys10 = yS(10);
766         int x = xs10, y = ys10;
767
768         add_subwindow(new BC_Title(x, y, _("Level:")));
769         x += xs70;
770         add_subwindow(scale = new DenoiseLevel(plugin, x, y));
771         show_window();
772         flush();
773 }
774
775
776
777 void DenoiseWindow::update()
778 {
779         scale->update(plugin->config.level);
780 }
781
782
783
784
785
786
787
788
789
790
791
792
793 DenoiseLevel::DenoiseLevel(DenoiseEffect *plugin, int x, int y)
794  : BC_FPot(x, y, (float)plugin->config.level, 0, 1.0)
795 {
796         this->plugin = plugin;
797         set_precision(0.01);
798 }
799
800 int DenoiseLevel::handle_event()
801 {
802         plugin->config.level = get_value();
803         plugin->send_configure_change();
804         return 1;
805 }
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821