1 /* Double Median Filter
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 #include "signpr_doubmed.h"
11 #include "signpr_general.h"
12 #include "errorwindow.h"
13 #ifndef SWIG
14 #include "stringinput.h"
15 #include "buttons.h"
16 #include "clrscr.h"
17 #include "boxes.h"
18 #include "helpline.h"
19 #endif
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #ifndef SWIG
24 #ifndef OLD_CURSES
25 #include <ncurses.h>
26 #else
27 #include <curses.h>
28 #endif
29 #endif
30 
31 
32 void
double_median_param_defaults(parampointer_t parampointer)33 double_median_param_defaults (parampointer_t parampointer)
34 {
35   parampointer->postlength1 = 2;
36   parampointer->prelength1 = 2;
37   parampointer->postlength2 = 2;
38   parampointer->prelength2 = 2;
39 }
40 
41 #ifndef SWIG
42 void
double_median_param_screen(parampointer_t parampointer)43 double_median_param_screen (parampointer_t parampointer)
44 {
45   stringinput_t medlength1str, medlength2str;
46   button_t ok_button, cancel_button;
47   int dont_stop = TRUE;
48   int returnval = 0;
49   int focus = 0;
50   int in_ch;
51   int i;
52   long helplong;
53 
54   char *helplines[4] =
55   {
56     " ^: more distortion.                    v: less effective against ticks.       ",
57     " ^: less correction of distortion.      v: more (faulty) correction.           ",
58     " Discard changes.                                                              ",
59     " Accept changes.                                                               "};
60 
61   medlength1str.maxlen = 500;
62   medlength1str.string = (char *) malloc (medlength1str.maxlen *
63 					  sizeof (char));
64   sprintf (medlength1str.string, "%ld", parampointer->prelength1 +
65 	   parampointer->postlength1 + 1);
66   medlength1str.y = 6;
67   medlength1str.x = 57;
68   medlength1str.w = 19;
69   medlength1str.cursorpos = strlen (medlength1str.string);
70   medlength1str.firstcharonscreen = 0;
71 
72   medlength2str.maxlen = 500;
73   medlength2str.string = (char *) malloc (medlength2str.maxlen *
74 					  sizeof (char));
75   sprintf (medlength2str.string, "%ld", parampointer->prelength2 +
76 	   parampointer->postlength2 + 1);
77   medlength2str.y = 8;
78   medlength2str.x = 57;
79   medlength2str.w = 19;
80   medlength2str.cursorpos = strlen (medlength2str.string);
81   medlength2str.firstcharonscreen = 0;
82 
83   ok_button.text = " OK ";
84   ok_button.y = 20;
85   ok_button.x = 71;
86   ok_button.selected = FALSE;
87 
88   cancel_button.text = " Cancel ";
89   cancel_button.y = 20;
90   cancel_button.x = 5;
91   cancel_button.selected = FALSE;
92 
93   clearscreen (SIGNPR_DOUBMED_PARAMSCR_HEADERTEXT);
94 
95   do
96     {
97       header (SIGNPR_DOUBMED_PARAMSCR_HEADERTEXT);
98 
99       if (focus == 2)
100 	cancel_button.selected = TRUE;
101       else
102 	cancel_button.selected = FALSE;
103 
104       if (focus == 3)
105 	ok_button.selected = TRUE;
106       else
107 	ok_button.selected = FALSE;
108 
109       mvprintw (3, 2,
110 	    "See the Signproc.txt file for the meaning of the parameters.");
111 
112       stringinput_display (&medlength1str);
113       mvprintw (medlength1str.y, 2,
114 		"Number of samples for the first median:");
115 
116       stringinput_display (&medlength2str);
117       mvprintw (medlength2str.y, 2,
118 		"Number of samples for the second (correction) median:");
119 
120       button_display (&cancel_button);
121       mybox (cancel_button.y - 1, cancel_button.x - 1,
122 	     3, strlen (cancel_button.text) + 2);
123       button_display (&ok_button);
124       mybox (ok_button.y - 1, ok_button.x - 1,
125 	     3, strlen (ok_button.text) + 2);
126 
127       helpline (helplines[focus]);
128 
129       switch (focus)
130 	{
131 	case 0:
132 	  stringinput_display (&medlength1str);
133 	  break;
134 	case 1:
135 	  stringinput_display (&medlength2str);
136 	  break;
137 	default:
138 	  move (0, 79);
139 	}
140 
141       refresh ();
142 
143       in_ch = getch ();
144 
145       switch (focus)
146 	{
147 	case 0:		/* medlength1str */
148 	  stringinput_stdkeys (in_ch, &medlength1str);
149 	  switch (in_ch)
150 	    {
151 	    case KEY_ENTER:
152 	    case 13:
153 	      i = sscanf (medlength1str.string, "%li", &helplong);
154 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
155 		error_window ("A whole, odd number, greater than 0, must \
156 be specified.");
157 	      else
158 		focus = 1;
159 	      break;
160 
161 	    case KEY_UP:
162 	      focus--;
163 	      break;
164 	    case KEY_DOWN:
165 	      focus++;
166 	      break;
167 	    }
168 	  break;
169 
170 	case 1:		/* medlength2str */
171 	  stringinput_stdkeys (in_ch, &medlength2str);
172 	  switch (in_ch)
173 	    {
174 	    case KEY_ENTER:
175 	    case 13:
176 	      i = sscanf (medlength2str.string, "%li", &helplong);
177 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
178 		error_window ("A whole, odd number, greater than 0, must \
179 be specified.");
180 	      else
181 		focus = 3;
182 	      break;
183 
184 	    case KEY_UP:
185 	      focus--;
186 	      break;
187 	    case KEY_DOWN:
188 	      focus++;
189 	      break;
190 	    }
191 	  break;
192 
193 	case 2:		/* Cancel */
194 	  switch (in_ch)
195 	    {
196 	    case KEY_ENTER:
197 	    case 13:
198 	      returnval = 0;
199 	      dont_stop = FALSE;
200 	      break;
201 
202 	    case KEY_LEFT:
203 	    case KEY_UP:
204 	      focus--;
205 	      break;
206 	    case KEY_RIGHT:
207 	    case KEY_DOWN:
208 	      focus++;
209 	      break;
210 	    }
211 	  break;
212 
213 	case 3:		/* OK */
214 	  switch (in_ch)
215 	    {
216 	    case KEY_ENTER:
217 	    case 13:
218 	      i = sscanf (medlength1str.string, "%li", &helplong);
219 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
220 		{
221 		  error_window ("A whole, odd number, greater than 0, must \
222 be specified as first median length.");
223 		  medlength1str.cursorpos =
224 		    strlen (medlength1str.string);
225 		  focus = 0;
226 		  break;
227 		}
228 
229 	      parampointer->prelength1 = (helplong - 1) / 2;
230 	      parampointer->postlength1 = (helplong - 1) / 2;
231 
232 	      i = sscanf (medlength2str.string, "%li", &helplong);
233 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
234 		{
235 		  error_window ("A whole, odd number, greater than 0, must \
236 be specified as second median length.");
237 		  medlength2str.cursorpos =
238 		    strlen (medlength2str.string);
239 		  focus = 1;
240 		  break;
241 		}
242 
243 	      parampointer->prelength2 = (helplong - 1) / 2;
244 	      parampointer->postlength2 = (helplong - 1) / 2;
245 
246 	      dont_stop = FALSE;
247 	      break;
248 
249 	    case KEY_LEFT:
250 	    case KEY_UP:
251 	      focus--;
252 	      break;
253 	    case KEY_RIGHT:
254 	    case KEY_DOWN:
255 	      focus++;
256 	      break;
257 	    }
258 	  break;
259 	}
260 
261       if (in_ch == 9)		/* TAB */
262 	focus++;
263 
264       if (in_ch == 27)
265 	dont_stop = FALSE;
266 
267       if (focus > 3)
268 	focus = 0;
269       if (focus < 0)
270 	focus = 3;
271     }
272   while (dont_stop);
273 
274   free (medlength1str.string);
275   free (medlength2str.string);
276 }
277 #endif
278 
279 void
init_double_median_filter(int filterno,parampointer_t parampointer)280 init_double_median_filter (int filterno, parampointer_t parampointer)
281 {
282   long total_post;
283 
284   total_post = parampointer->postlength2;
285   if (parampointer->postlength1 > total_post)
286     total_post = parampointer->postlength1;
287 
288   parampointer->buffer = init_buffer (total_post,
289 				      parampointer->prelength1 +
290 				      parampointer->prelength2);
291   parampointer->buffer2 = init_buffer (parampointer->postlength2,
292 				       parampointer->prelength2);
293 
294   parampointer->filterno = filterno;
295 }
296 
297 void
delete_double_median_filter(parampointer_t parampointer)298 delete_double_median_filter (parampointer_t parampointer)
299 {
300   delete_buffer (&parampointer->buffer);
301   delete_buffer (&parampointer->buffer2);
302 }
303 
304 sample_t
double_median_1(long offset,long offset_zero,parampointer_t parampointer)305 double_median_1 (long offset, long offset_zero,
306 		 parampointer_t parampointer)
307 {
308   sample_t sample;
309   signed short list1[parampointer->postlength1 + parampointer->prelength1 + 1];
310   signed short list2[parampointer->postlength1 + parampointer->prelength1 + 1];
311   long i;
312 
313   for (i = 0; i <= parampointer->postlength1 +
314        parampointer->prelength1; i++)
315     {
316       sample = get_from_buffer (&parampointer->buffer,
317 				i - parampointer->postlength1 +
318 				offset + offset_zero);
319       list1[i] = sample.left;
320       list2[i] = sample.right;
321     }
322 
323   sample.left = median (list1, parampointer->postlength1 +
324 			parampointer->prelength1 + 1);
325   sample.right = median (list2, parampointer->postlength1 +
326 			 parampointer->prelength1 + 1);
327   return sample;
328 }
329 
330 fillfuncpointer_t double_median_1_pointer = double_median_1;
331 
332 sample_t
333 #ifndef SWIG
double_median_filter(parampointer_t parampointer)334 double_median_filter (parampointer_t parampointer)
335 #else
336 double_median_filter (parampointer_t parampointer, int *filter_type)
337 #endif
338 {
339   sample_t sample;
340   sample_t sample2;
341   sample_t returnval;
342   signed short list1[parampointer->postlength2 + parampointer->prelength2 + 1];
343   signed short list2[parampointer->postlength2 + parampointer->prelength2 + 1];
344   long i, j;
345 
346 #ifndef SWIG
347   advance_current_pos (&parampointer->buffer, parampointer->filterno);
348 #else
349   advance_current_pos (&parampointer->buffer, parampointer->filterno, filter_type);
350 #endif
351 
352   advance_current_pos_custom (&parampointer->buffer2,
353 			      double_median_1_pointer,
354 			      0,
355 			      parampointer);
356 
357 
358   for (i = 0; i <= parampointer->postlength2 +
359        parampointer->prelength2; i++)
360     {
361       sample = get_from_buffer (&parampointer->buffer,
362 				i - parampointer->postlength2);
363       sample2 = get_from_buffer (&parampointer->buffer2,
364 				 i - parampointer->postlength2);
365 
366       j = sample.left - sample2.left;
367       j /= 2;
368       list1[i] = j;
369 
370       j = sample.right - sample2.right;
371       j /= 2;
372       list2[i] = j;
373     }
374 
375   sample2 = get_from_buffer (&parampointer->buffer2, 0);
376 
377   returnval.left = median (list1, parampointer->postlength2 +
378 			   parampointer->prelength2 + 1) * 2
379     + sample2.left;
380 
381   returnval.right = median (list2, parampointer->postlength2 +
382 			    parampointer->prelength2 + 1) * 2
383     + sample2.right;
384 
385   return returnval;
386 }
387