1 /* General functions for signal processing
2
3 * Copyright (C) 1998 J.A. Bezemer
4 *
5 * Licensed under the terms of the GNU General Public License.
6 * ABSOLUTELY NO WARRANTY.
7 * See the file `COPYING' in this directory.
8 */
9
10
11 #include "signpr_general.h"
12 #ifndef SWIG
13 #include "scrollmenu.h"
14 #endif
15 #include "signpr_median.h"
16 #include "signpr_wav.h"
17 #include "signpr_cmf.h"
18 #include "signpr_cmf2.h"
19 #include "signpr_cmf3.h"
20 #include "signpr_mean.h"
21 #include "signpr_doubmed.h"
22 #include "signpr_rms.h"
23 #include "signpr_copy.h"
24 #include "signpr_exper.h"
25 #include "signpr_mono.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #ifndef SWIG
30 #ifndef OLD_CURSES
31 #include <ncurses.h>
32 #else
33 #include <curses.h>
34 #endif
35 #endif
36
37
38 #ifndef SWIG
39 void
write_sample_to_screen(sample_t data)40 write_sample_to_screen (sample_t data)
41 {
42 printf ("Output, left & right: %d %d\n", data.left, data.right);
43 }
44
45 sample_t
read_from_keyboard()46 read_from_keyboard ()
47 {
48 sample_t inputsample;
49 signed int left; /* 'standard int' for %d */
50 signed int right;
51
52 printf ("Please enter left & right sample: ");
53
54 scanf ("%d %d", &(left), &(right));
55
56 inputsample.left = left;
57 inputsample.right = right;
58
59 return inputsample;
60 }
61 #endif /* SWIG */
62
63
64
65 parampointer_t parampointerarray[MAX_FILTERS];
66
67 #ifndef SWIG
68 int filter_type[MAX_FILTERS];
69 #endif /* SWIG */
70
71 int number_of_filters;
72
73 /* ----- BUFFER ------------------------------------------------------------ */
74
75 buffer_t
init_buffer(long post_length,long pre_length)76 init_buffer (long post_length, long pre_length)
77 {
78 buffer_t newbuffer;
79 long bufferlength;
80
81 bufferlength = pre_length + post_length + 1;
82
83 newbuffer.array = (sample_t *) malloc (bufferlength *
84 sizeof (sample_t));
85 newbuffer.currpos = -1;
86 newbuffer.arraylength = bufferlength;
87 newbuffer.pre_length = pre_length;
88 newbuffer.post_length = post_length;
89
90 #ifdef TURBO_BUFFER
91 {
92 int i;
93 int tablesize = bufferlength * 3;
94 newbuffer.indextable = (int *) malloc (tablesize *
95 sizeof (int));
96 newbuffer.indextable += bufferlength;
97 for (i = -bufferlength; i < 2 * bufferlength; i++)
98 {
99 newbuffer.indextable[i] = (i + bufferlength) % bufferlength;
100 }
101 }
102 #endif
103
104 return newbuffer;
105 }
106
107 void
delete_buffer(buffer_t * buffer)108 delete_buffer (buffer_t * buffer)
109 {
110 #ifdef TURBO_BUFFER
111 free (buffer->indextable - buffer->arraylength);
112 #endif
113 buffer->arraylength = 0;
114 buffer->pre_length = 0;
115 buffer->post_length = 0;
116 free (buffer->array);
117 }
118
119 #ifndef TURBO_BUFFER
120
121 sample_t
get_from_buffer(buffer_t * buffer,long offset)122 get_from_buffer (buffer_t * buffer, long offset)
123 {
124 long realpos;
125
126 if ((offset > buffer->pre_length)
127 || (-offset > buffer->post_length))
128 {
129 fprintf (stderr, "ERROR: get_from_buffer #1 - offset=%ld\n", offset);
130 }
131
132 realpos = buffer->currpos + offset;
133
134 if (realpos < 0)
135 realpos += buffer->arraylength;
136
137 if (realpos >= buffer->arraylength)
138 realpos -= buffer->arraylength;
139
140 return (buffer->array)[realpos];
141 }
142
143 void
put_in_buffer(buffer_t * buffer,long offset,sample_t sample)144 put_in_buffer (buffer_t * buffer, long offset, sample_t sample)
145 {
146 long realpos;
147
148 if ((offset > buffer->pre_length)
149 || (-offset > buffer->post_length))
150 {
151 fprintf (stderr, "ERROR (put_in_buffer #1)\n");
152 }
153
154 realpos = buffer->currpos + offset;
155
156 if (realpos < 0)
157 realpos += buffer->arraylength;
158
159 if (realpos >= buffer->arraylength)
160 realpos -= buffer->arraylength;
161
162 (buffer->array)[realpos] = sample;
163 }
164
165 #endif /* ndef TURBO_BUFFER */
166
167 void
168 #ifndef SWIG
advance_current_pos(buffer_t * buffer,int filterno)169 advance_current_pos (buffer_t * buffer, int filterno)
170 #else
171 advance_current_pos (buffer_t * buffer, int filterno, int *filter_type)
172 #endif
173 {
174 long i;
175
176 if (buffer->currpos < 0) /* just newly created */
177 {
178 for (i = 0; i <= buffer->post_length; i++)
179 {
180 /* fill first part with zeroes */
181 (buffer->array)[i].left = 0;
182 (buffer->array)[i].right = 0;
183 }
184
185 buffer->currpos = buffer->post_length;
186
187 for (i = 0; i <= buffer->pre_length; i++)
188 {
189 (buffer->array)[buffer->currpos + i] =
190 #ifndef SWIG
191 get_sample_from_filter (filterno - 1);
192 #else
193 get_sample_from_filter (filterno - 1, filter_type);
194 #endif
195 }
196
197 }
198 else
199 {
200 buffer->currpos++;
201
202 if (buffer->currpos >= buffer->arraylength)
203 buffer->currpos -= buffer->arraylength;
204
205 i = buffer->currpos + buffer->pre_length;
206
207 if (i >= buffer->arraylength)
208 i -= buffer->arraylength;
209
210 #ifndef SWIG
211 (buffer->array)[i] = get_sample_from_filter (filterno - 1);
212 #else
213 (buffer->array)[i] = get_sample_from_filter (filterno - 1, filter_type);
214 #endif
215 }
216 }
217
218 void
advance_current_pos_custom(buffer_t * buffer,fillfuncpointer_t fillfunc,long offset_zero,parampointer_t parampointer)219 advance_current_pos_custom (buffer_t * buffer, fillfuncpointer_t fillfunc,
220 long offset_zero, parampointer_t parampointer)
221 {
222 long i;
223
224 if (buffer->currpos < 0) /* just newly created */
225 {
226 for (i = 0; i <= buffer->post_length; i++)
227 {
228 /* fill first part with zeroes */
229 (buffer->array)[i].left = 0;
230 (buffer->array)[i].right = 0;
231 }
232
233 buffer->currpos = buffer->post_length;
234
235 for (i = 0; i <= buffer->pre_length; i++)
236 {
237 (buffer->array)[buffer->currpos + i] =
238 fillfunc (i, offset_zero, parampointer);
239 }
240
241 }
242 else
243 {
244 buffer->currpos++;
245
246 if (buffer->currpos >= buffer->arraylength)
247 buffer->currpos -= buffer->arraylength;
248
249 i = buffer->currpos + buffer->pre_length;
250
251 if (i >= buffer->arraylength)
252 i -= buffer->arraylength;
253
254 (buffer->array)[i] = fillfunc (buffer->pre_length, offset_zero,
255 parampointer);
256 }
257 }
258
259 /* ----- QUICK SORT -------------------------------------------------------- */
260
261 /* For arrays of `signed short' with max. length of 32767. */
262
263 /* Adapted from Ammeraal, L., `Ansi C', 2nd ed., Schoonhoven (The
264 Netherlands): Academic Service, 1993. */
265
266 void
qsort2(signed short * a,int n)267 qsort2 (signed short *a, int n) /* a: pointer to start of array */
268 { /* n: # elements in array */
269 int i, j;
270 signed short x, w;
271
272 do
273 {
274 i = 0;
275 j = n - 1;
276 x = a[j / 2];
277 do
278 {
279 while (a[i] < x)
280 i++;
281 while (a[j] > x)
282 j--;
283 if (i > j)
284 break;
285 w = a[i];
286 a[i] = a[j];
287 a[j] = w;
288 }
289 while (++i <= --j);
290 if (j + 1 < n - i)
291 {
292 if (j > 0)
293 qsort2 (a, j + 1);
294 a += i;
295 n -= i;
296 }
297 else
298 {
299 if (i < n - 1)
300 qsort2 (a + i, n - i);
301 n = j + 1;
302 }
303 }
304 while (n > 1);
305 }
306
307 /* And one for doubles, max size 2G */
308
309 void
qsort2double(double * a,long n)310 qsort2double (double *a, long n)
311 /* a: pointer to start of array */
312 { /* n: # elements in array */
313 long i, j;
314 double x, w;
315
316 do
317 {
318 i = 0;
319 j = n - 1;
320 x = a[j / 2];
321 do
322 {
323 while (a[i] < x)
324 i++;
325 while (a[j] > x)
326 j--;
327 if (i > j)
328 break;
329 w = a[i];
330 a[i] = a[j];
331 a[j] = w;
332 }
333 while (++i <= --j);
334 if (j + 1 < n - i)
335 {
336 if (j > 0)
337 qsort2double (a, j + 1);
338 a += i;
339 n -= i;
340 }
341 else
342 {
343 if (i < n - 1)
344 qsort2double (a + i, n - i);
345 n = j + 1;
346 }
347 }
348 while (n > 1);
349 }
350
351 /* ----- MEDIAN FUNCTION --------------------------------------------------- */
352
353 /* For arrays of 'signed short' with max. length of 32767.
354
355 NOTE: The array will be affected (most likely: sorted). Do not use
356 the array after calling median() !
357
358 Examples: {2,5,4,1,3} ==sort==> {1,2,3,4,5} ==returns==> 3
359
360 {2,5,4,1,6,3} ==sort==> {1,2,3,4,5,6} ==returns==> 3
361 */
362
363 #ifdef TURBO_MEDIAN
364
365 #ifndef MEDIAN_THRESHOLD
366 #define MEDIAN_THRESHOLD 5
367 #endif
368
369 signed short
median(signed short * a,int n)370 median (signed short *a, int n)
371 {
372 int i, j, k;
373 signed short x, w, t1, t2;
374 int low, mid, high;
375
376 low = 0;
377 mid = n / 2;
378 high = n - 1;
379
380 while (high - low > MEDIAN_THRESHOLD)
381 {
382 i = low;
383 j = high;
384 t1 = a[i];
385 t2 = a[j];
386 if (t1 > t2)
387 {
388 x = t1;
389 t1 = t2;
390 t2 = x;
391 }
392 x = a[(low + high) / 2];
393 if (x < t1)
394 {
395 x = t1;
396 }
397 else if (x > t2)
398 {
399 x = t2;
400 }
401 do
402 {
403 while (a[i] < x)
404 i++;
405 while (a[j] > x)
406 j--;
407 if (i > j)
408 break;
409 w = a[i];
410 a[i] = a[j];
411 a[j] = w;
412 }
413 while (++i <= --j);
414 if (i <= mid)
415 {
416 low = i;
417 }
418 else
419 {
420 high = j;
421 }
422 }
423 for (i = low; i <= mid; i++)
424 {
425 k = i;
426 w = a[i];
427 for (j = i + 1; j <= high; j++)
428 {
429 if (a[j] < w)
430 {
431 k = j;
432 w = a[j];
433 }
434 }
435 if (k != i)
436 {
437 a[k] = a[i];
438 a[i] = w;
439 }
440 }
441 return a[mid];
442 }
443
444 #else /* if not TURBO_MEDIAN */
445
446 signed short
median(signed short * a,int n)447 median (signed short *a, int n)
448 { /* a: pointer to start of array */
449 qsort2 (a, n); /* n: # elements in array */
450
451 return a[((n + 1) / 2) - 1]; /* (10+1)/2 = 5 (11+1)/2 = 6 */
452 }
453
454 #endif /* (not) TURBO_MEDIAN */
455
456 #ifndef SWIG
457
458 /* ----- BUILDING THE LIST OF FILTERS -------------------------------------- */
459
460 void
add_to_filterlist(scrollmenu_t * filtlist,int * filtnumbers,char ** helptexts,int filternumber,char * filtername,char * helptext)461 add_to_filterlist (scrollmenu_t * filtlist, int *filtnumbers,
462 char **helptexts, int filternumber, char *filtername,
463 char *helptext)
464 {
465 filtlist->items[filtlist->number] = filtername;
466 filtnumbers[filtlist->number] = filternumber;
467 helptexts[filtlist->number] = helptext;
468
469 filtlist->number++;
470 }
471
472 void
make_filterlist(scrollmenu_t * filtlist,int * filtnumbers,char ** helptexts)473 make_filterlist (scrollmenu_t * filtlist, int *filtnumbers,
474 char **helptexts)
475 {
476 filtlist->number = 0;
477
478 add_to_filterlist (filtlist,
479 filtnumbers,
480 helptexts,
481 COPYONLY_FILTER,
482 COPYONLY_NAME,
483 COPYONLY_HELPTEXT);
484
485 add_to_filterlist (filtlist,
486 filtnumbers,
487 helptexts,
488 MONOIZE_FILTER,
489 MONOIZE_NAME,
490 MONOIZE_HELPTEXT);
491
492 add_to_filterlist (filtlist,
493 filtnumbers,
494 helptexts,
495 SIMPLE_MEDIAN_FILTER,
496 SIMPLE_MEDIAN_NAME,
497 SIMPLE_MEDIAN_HELPTEXT);
498
499 add_to_filterlist (filtlist,
500 filtnumbers,
501 helptexts,
502 DOUBLE_MEDIAN_FILTER,
503 DOUBLE_MEDIAN_NAME,
504 DOUBLE_MEDIAN_HELPTEXT);
505
506 add_to_filterlist (filtlist,
507 filtnumbers,
508 helptexts,
509 SIMPLE_MEAN_FILTER,
510 SIMPLE_MEAN_NAME,
511 SIMPLE_MEAN_HELPTEXT);
512
513 add_to_filterlist (filtlist,
514 filtnumbers,
515 helptexts,
516 RMS_FILTER,
517 RMS_NAME,
518 RMS_HELPTEXT);
519
520 add_to_filterlist (filtlist,
521 filtnumbers,
522 helptexts,
523 COND_MEDIAN_FILTER,
524 COND_MEDIAN_NAME,
525 COND_MEDIAN_HELPTEXT);
526
527 add_to_filterlist (filtlist,
528 filtnumbers,
529 helptexts,
530 COND_MEDIAN2_FILTER,
531 COND_MEDIAN2_NAME,
532 COND_MEDIAN2_HELPTEXT);
533
534 add_to_filterlist (filtlist,
535 filtnumbers,
536 helptexts,
537 COND_MEDIAN3_FILTER,
538 COND_MEDIAN3_NAME,
539 COND_MEDIAN3_HELPTEXT);
540
541 add_to_filterlist (filtlist,
542 filtnumbers,
543 helptexts,
544 EXPERIMENT_FILTER,
545 EXPERIMENT_NAME,
546 EXPERIMENT_HELPTEXT);
547
548 }
549 #endif /* SWIG */
550
551 /* ----- GET SAMPLE FROM FILTER -------------------------------------------- */
552
553 sample_t
554 #ifndef SWIG
get_sample_from_filter(int filterno)555 get_sample_from_filter (int filterno)
556 #else
557 get_sample_from_filter (int filterno, int *filter_type)
558 #endif
559 {
560 if (filterno == -1)
561 return readsamplesource ();
562 else
563 switch (filter_type[filterno])
564 {
565 case SIMPLE_MEDIAN_FILTER:
566 #ifndef SWIG
567 return simple_median_filter (parampointerarray[filterno]);
568 #else
569 return simple_median_filter (parampointerarray[filterno], filter_type);
570 #endif
571 break;
572
573 case SIMPLE_MEAN_FILTER:
574 #ifndef SWIG
575 return simple_mean_filter (parampointerarray[filterno]);
576 #else
577 return simple_mean_filter (parampointerarray[filterno], filter_type);
578 #endif
579 break;
580
581 case COND_MEDIAN_FILTER:
582 #ifndef SWIG
583 return cond_median_filter (parampointerarray[filterno]);
584 #else
585 return cond_median_filter (parampointerarray[filterno], filter_type);
586 #endif
587 break;
588
589 case DOUBLE_MEDIAN_FILTER:
590 #ifndef SWIG
591 return double_median_filter (parampointerarray[filterno]);
592 #else
593 return double_median_filter (parampointerarray[filterno], filter_type);
594 #endif
595 break;
596
597 case COND_MEDIAN2_FILTER:
598 #ifndef SWIG
599 return cond_median2_filter (parampointerarray[filterno]);
600 #else
601 return cond_median2_filter (parampointerarray[filterno], filter_type);
602 #endif
603 break;
604
605 case RMS_FILTER:
606 #ifndef SWIG
607 return rms_filter (parampointerarray[filterno]);
608 #else
609 return rms_filter (parampointerarray[filterno], filter_type);
610 #endif
611 break;
612
613 case COPYONLY_FILTER:
614 #ifndef SWIG
615 return copyonly_filter (parampointerarray[filterno]);
616 #else
617 return copyonly_filter (parampointerarray[filterno], filter_type);
618 #endif
619 break;
620
621 case MONOIZE_FILTER:
622 #ifndef SWIG
623 return monoize_filter (parampointerarray[filterno]);
624 #else
625 return monoize_filter (parampointerarray[filterno], filter_type);
626 #endif
627 break;
628
629 case COND_MEDIAN3_FILTER:
630 return cond_median3_filter (parampointerarray[filterno]);
631 break;
632
633 case EXPERIMENT_FILTER:
634 #ifndef SWIG
635 return experiment_filter (parampointerarray[filterno]);
636 #else
637 return experiment_filter (parampointerarray[filterno], filter_type);
638 #endif
639 break;
640
641 default:
642 printf ("Error (get_sample_from_filter): wrong filter");
643 exit (2);
644 break;
645 }
646 }
647
648 /* ----- INIT FILTERS ------------------------------------------------------ */
649
650 void
651 #ifndef SWIG
init_filters()652 init_filters ()
653 #else
654 init_filters (int number_of_filters, int *filter_type)
655 #endif
656 {
657 int i;
658
659 for (i = 0; i < number_of_filters; i++)
660 switch (filter_type[i])
661 {
662 case 0:
663 break;
664
665 case SIMPLE_MEDIAN_FILTER:
666 init_simple_median_filter (i, parampointerarray[i]);
667 break;
668
669 case SIMPLE_MEAN_FILTER:
670 init_simple_mean_filter (i, parampointerarray[i]);
671 break;
672
673 case COND_MEDIAN_FILTER:
674 init_cond_median_filter (i, parampointerarray[i]);
675 break;
676
677 case DOUBLE_MEDIAN_FILTER:
678 init_double_median_filter (i, parampointerarray[i]);
679 break;
680
681 case COND_MEDIAN2_FILTER:
682 init_cond_median2_filter (i, parampointerarray[i]);
683 break;
684
685 case RMS_FILTER:
686 init_rms_filter (i, parampointerarray[i]);
687 break;
688
689 case COPYONLY_FILTER:
690 init_copyonly_filter (i, parampointerarray[i]);
691 break;
692
693 case MONOIZE_FILTER:
694 init_monoize_filter (i, parampointerarray[i]);
695 break;
696
697 case COND_MEDIAN3_FILTER:
698 init_cond_median3_filter (i, parampointerarray[i]);
699 break;
700
701 case EXPERIMENT_FILTER:
702 init_experiment_filter (i, parampointerarray[i]);
703 break;
704
705 default:
706 printf ("Error (init_filters): wrong filter");
707 exit (2);
708 break;
709 }
710 }
711
712 /* ----- DELETE FILTERS ------------------------------------------------------ */
713
714 void
715 #ifndef SWIG
delete_filters()716 delete_filters ()
717 #else
718 delete_filters (int *filter_type)
719 #endif
720 {
721 int i;
722
723 for (i = 0; i < number_of_filters; i++)
724 switch (filter_type[i])
725 {
726 case 0:
727 break;
728
729 case SIMPLE_MEDIAN_FILTER:
730 delete_simple_median_filter (parampointerarray[i]);
731 break;
732
733 case SIMPLE_MEAN_FILTER:
734 delete_simple_mean_filter (parampointerarray[i]);
735 break;
736
737 case COND_MEDIAN_FILTER:
738 delete_cond_median_filter (parampointerarray[i]);
739 break;
740
741 case DOUBLE_MEDIAN_FILTER:
742 delete_double_median_filter (parampointerarray[i]);
743 break;
744
745 case COND_MEDIAN2_FILTER:
746 delete_cond_median2_filter (parampointerarray[i]);
747 break;
748
749 case RMS_FILTER:
750 delete_rms_filter (parampointerarray[i]);
751 break;
752
753 case COPYONLY_FILTER:
754 delete_copyonly_filter (parampointerarray[i]);
755 break;
756
757
758 case MONOIZE_FILTER:
759 delete_monoize_filter (parampointerarray[i]);
760 break;
761
762 case COND_MEDIAN3_FILTER:
763 delete_cond_median3_filter (parampointerarray[i]);
764 break;
765
766 case EXPERIMENT_FILTER:
767 delete_experiment_filter (parampointerarray[i]);
768 break;
769
770 default:
771 printf ("Error (delete_filters): wrong filter");
772 exit (2);
773 break;
774 }
775 }
776
777 /* ----- PARAM DEFAULTS ---------------------------------------------------- */
778
779 void
param_defaults(parampointer_t parampointer,int filtertype)780 param_defaults (parampointer_t parampointer, int filtertype)
781 {
782 switch (filtertype)
783 {
784 case 0: /* nothing needed */
785 break;
786
787 case SIMPLE_MEDIAN_FILTER:
788 simple_median_param_defaults (parampointer);
789 break;
790
791 case SIMPLE_MEAN_FILTER:
792 simple_mean_param_defaults (parampointer);
793 break;
794
795 case COND_MEDIAN_FILTER:
796 cond_median_param_defaults (parampointer);
797 break;
798
799 case DOUBLE_MEDIAN_FILTER:
800 double_median_param_defaults (parampointer);
801 break;
802
803 case COND_MEDIAN2_FILTER:
804 cond_median2_param_defaults (parampointer);
805 break;
806
807 case RMS_FILTER:
808 rms_param_defaults (parampointer);
809 break;
810
811 case COPYONLY_FILTER:
812 copyonly_param_defaults (parampointer);
813 break;
814
815 case MONOIZE_FILTER:
816 monoize_param_defaults (parampointer);
817 break;
818
819 case COND_MEDIAN3_FILTER:
820 cond_median3_param_defaults (parampointer);
821 break;
822
823 case EXPERIMENT_FILTER:
824 experiment_param_defaults (parampointer);
825 break;
826
827 default:
828 printf ("Error (praram_defaults): wrong filter");
829 exit (2);
830 break;
831 }
832 }
833
834 /* ----- PARAM SCREEN ------------------------------------------------------ */
835
836 #ifndef SWIG
837 void
param_screen(parampointer_t parampointer,int filtertype)838 param_screen (parampointer_t parampointer, int filtertype)
839 {
840 switch (filtertype)
841 {
842 case 0: /* nothing needed */
843 break;
844
845 case SIMPLE_MEDIAN_FILTER:
846 simple_median_param_screen (parampointer);
847 break;
848
849 case SIMPLE_MEAN_FILTER:
850 simple_mean_param_screen (parampointer);
851 break;
852
853 case COND_MEDIAN_FILTER:
854 cond_median_param_screen (parampointer);
855 break;
856
857 case DOUBLE_MEDIAN_FILTER:
858 double_median_param_screen (parampointer);
859 break;
860
861 case COND_MEDIAN2_FILTER:
862 cond_median2_param_screen (parampointer);
863 break;
864
865 case RMS_FILTER:
866 rms_param_screen (parampointer);
867 break;
868
869 case COPYONLY_FILTER:
870 copyonly_param_screen (parampointer);
871 break;
872
873 case MONOIZE_FILTER:
874 monoize_param_screen (parampointer);
875 break;
876
877 case COND_MEDIAN3_FILTER:
878 cond_median3_param_screen (parampointer);
879 break;
880
881 case EXPERIMENT_FILTER:
882 experiment_param_screen (parampointer);
883 break;
884
885 default:
886 printf ("Error (praram_screen): wrong filter");
887 exit (2);
888 break;
889 }
890
891 clear ();
892 refresh ();
893 }
894 #endif /* SWIG */
895