1 /* Conditional 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 /* Remove the `dont' to get b[t].left on left channel and g[t].left on
11    right channel - useful for verifying properties.
12 
13    Note that
14    b[t] is z[t] if RMSlength=RMFlength=1
15    and
16    b[t] is w[t] if RMFlength=1
17    (See also Signproc.txt)
18  */
19 #define dontVIEW_INTERNALS
20 
21 
22 #include "signpr_cmf.h"
23 #include "signpr_general.h"
24 #include "errorwindow.h"
25 #ifndef SWIG
26 #include "stringinput.h"
27 #include "buttons.h"
28 #include "clrscr.h"
29 #include "boxes.h"
30 #include "helpline.h"
31 #include "yesnowindow.h"
32 #endif
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <math.h>
37 #ifndef SWIG
38 #ifndef OLD_CURSES
39 #include <ncurses.h>
40 #else
41 #include <curses.h>
42 #endif
43 #endif
44 
45 
46 /* Macros I used first:
47 
48    COND_MEDIAN_MF_POSTLENGTH   ==  parampointer->postlength1
49    COND_MEDIAN_MF_PRELENGTH    ==  parampointer->prelength1
50 
51    COND_MEDIAN_RMS_POSTLENGTH  ==  parampointer->postlength2
52    COND_MEDIAN_RMS_PRELENGTH   ==  parampointer->prelength2
53 
54    COND_MEDIAN_RMF_POSTLENGTH  ==  parampointer->postlength3
55    COND_MEDIAN_RMF_PRELENGTH   ==  parampointer->prelength3
56 
57    COND_MEDIAN_RMF_DECIMATE    ==  parampointer->int1
58 
59    COND_MEDIAN_THRESHOLD       ==  parampointer->long1
60  */
61 
62 
63 void
cond_median_param_defaults(parampointer_t parampointer)64 cond_median_param_defaults (parampointer_t parampointer)
65 {
66   /* Best tick-reduction: 21 - 9 - 11 - 5 - 2500 */
67 
68   parampointer->postlength1 = 10;
69   parampointer->prelength1 = 10;
70   parampointer->postlength2 = 4;
71   parampointer->prelength2 = 4;
72   parampointer->postlength3 = 5;
73   parampointer->prelength3 = 5;
74   parampointer->int1 = 5;	/* actually, this should really be 12 */
75   parampointer->long1 = 2500;
76 
77   /* If you experience badly affected sound, try 15 - 11 - 9 - 4 - 2500 */
78 }
79 
80 #ifndef SWIG
81 void
cond_median_param_screen(parampointer_t parampointer)82 cond_median_param_screen (parampointer_t parampointer)
83 {
84   stringinput_t medlengthstr, rmslengthstr, rmflengthstr, decimatestr,
85     thresholdstr;
86   button_t ok_button, cancel_button, defaults_button;
87   int dont_stop = TRUE;
88   int focus = 0;
89   int in_ch;
90   int i;
91   long helplong;
92 
93   char *helplines[8] =
94   {
95     " ^: no neat interpolation.              v: broad ticks not filtered out.       ",
96     " ^: less ticks detected.                v: not all of tick interpolated.       ",
97     " ^: bad following of dynamics.          v: fewer ticks detected.               ",
98     " ^: bad following of dynamics.          v: fewer ticks detected.               ",
99     " ^: only strong ticks detected.         v: music-ticks also filtered out.      ",
100     " Discard changes.                                                              ",
101     " Reset default values.                                                         ",
102     " Accept changes.                                                               "};
103 
104   medlengthstr.maxlen = 500;
105   medlengthstr.string = (char *) malloc (medlengthstr.maxlen *
106 					 sizeof (char));
107   sprintf (medlengthstr.string, "%ld", parampointer->prelength1 +
108 	   parampointer->postlength1 + 1);
109   medlengthstr.y = 6;
110   medlengthstr.x = 57;
111   medlengthstr.w = 19;
112   medlengthstr.cursorpos = strlen (medlengthstr.string);
113   medlengthstr.firstcharonscreen = 0;
114 
115   rmslengthstr.maxlen = 500;
116   rmslengthstr.string = (char *) malloc (rmslengthstr.maxlen *
117 					 sizeof (char));
118   sprintf (rmslengthstr.string, "%ld", parampointer->prelength2 +
119 	   parampointer->postlength2 + 1);
120   rmslengthstr.y = 8;
121   rmslengthstr.x = 57;
122   rmslengthstr.w = 19;
123   rmslengthstr.cursorpos = strlen (rmslengthstr.string);
124   rmslengthstr.firstcharonscreen = 0;
125 
126   rmflengthstr.maxlen = 500;
127   rmflengthstr.string = (char *) malloc (rmflengthstr.maxlen *
128 					 sizeof (char));
129   sprintf (rmflengthstr.string, "%ld", parampointer->prelength3 +
130 	   parampointer->postlength3 + 1);
131   rmflengthstr.y = 10;
132   rmflengthstr.x = 57;
133   rmflengthstr.w = 19;
134   rmflengthstr.cursorpos = strlen (rmflengthstr.string);
135   rmflengthstr.firstcharonscreen = 0;
136 
137   decimatestr.maxlen = 500;
138   decimatestr.string = (char *) malloc (decimatestr.maxlen *
139 					sizeof (char));
140   sprintf (decimatestr.string, "%d", parampointer->int1);
141   decimatestr.y = 12;
142   decimatestr.x = 57;
143   decimatestr.w = 19;
144   decimatestr.cursorpos = strlen (decimatestr.string);
145   decimatestr.firstcharonscreen = 0;
146 
147   thresholdstr.maxlen = 500;
148   thresholdstr.string = (char *) malloc (thresholdstr.maxlen *
149 					 sizeof (char));
150   sprintf (thresholdstr.string, "%ld", parampointer->long1);
151   thresholdstr.y = 14;
152   thresholdstr.x = 57;
153   thresholdstr.w = 19;
154   thresholdstr.cursorpos = strlen (thresholdstr.string);
155   thresholdstr.firstcharonscreen = 0;
156 
157   ok_button.text = " OK ";
158   ok_button.y = 20;
159   ok_button.x = 71;
160   ok_button.selected = FALSE;
161 
162   cancel_button.text = " Cancel ";
163   cancel_button.y = 20;
164   cancel_button.x = 5;
165   cancel_button.selected = FALSE;
166 
167   defaults_button.text = " Defaults ";
168   defaults_button.y = 20;
169   defaults_button.x = 36;
170   defaults_button.selected = FALSE;
171 
172   clearscreen (SIGNPR_CMF_PARAMSCR_HEADERTEXT);
173 
174   do
175     {
176       header (SIGNPR_CMF_PARAMSCR_HEADERTEXT);
177 
178       if (focus == 5)
179 	cancel_button.selected = TRUE;
180       else
181 	cancel_button.selected = FALSE;
182 
183       if (focus == 6)
184 	defaults_button.selected = TRUE;
185       else
186 	defaults_button.selected = FALSE;
187 
188       if (focus == 7)
189 	ok_button.selected = TRUE;
190       else
191 	ok_button.selected = FALSE;
192 
193       mvprintw (3, 2,
194 	    "See the Signproc.txt file for the meaning of the parameters.");
195 
196       stringinput_display (&medlengthstr);
197       mvprintw (medlengthstr.y, 2,
198 		"Number of samples for median to interpolate ticks:");
199 
200       stringinput_display (&rmslengthstr);
201       mvprintw (rmslengthstr.y, 2,
202 		"Length of the RMS operation (samples):");
203 
204       stringinput_display (&rmflengthstr);
205       mvprintw (rmflengthstr.y, 2,
206 		"Length of the recursive median operation (samples):");
207 
208       stringinput_display (&decimatestr);
209       mvprintw (decimatestr.y, 2,
210 		"Decimation factor for the recursive median:");
211 
212       stringinput_display (&thresholdstr);
213       mvprintw (thresholdstr.y, 2,
214 		"Threshold for tick detection (thousandths):");
215 
216       button_display (&cancel_button);
217       mybox (cancel_button.y - 1, cancel_button.x - 1,
218 	     3, strlen (cancel_button.text) + 2);
219       button_display (&defaults_button);
220       mybox (defaults_button.y - 1, defaults_button.x - 1,
221 	     3, strlen (defaults_button.text) + 2);
222       button_display (&ok_button);
223       mybox (ok_button.y - 1, ok_button.x - 1,
224 	     3, strlen (ok_button.text) + 2);
225 
226       helpline (helplines[focus]);
227 
228       switch (focus)
229 	{
230 	case 0:
231 	  stringinput_display (&medlengthstr);
232 	  break;
233 	case 1:
234 	  stringinput_display (&rmslengthstr);
235 	  break;
236 	case 2:
237 	  stringinput_display (&rmflengthstr);
238 	  break;
239 	case 3:
240 	  stringinput_display (&decimatestr);
241 	  break;
242 	case 4:
243 	  stringinput_display (&thresholdstr);
244 	  break;
245 	default:
246 	  move (0, 79);
247 	}
248 
249       refresh ();
250 
251       in_ch = getch ();
252 
253       switch (focus)
254 	{
255 	case 0:		/* medlengthstr */
256 	  stringinput_stdkeys (in_ch, &medlengthstr);
257 	  switch (in_ch)
258 	    {
259 	    case KEY_ENTER:
260 	    case 13:
261 	      i = sscanf (medlengthstr.string, "%li", &helplong);
262 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
263 		error_window ("A whole, odd number, greater than 0, must \
264 be specified.");
265 	      else
266 		focus++;
267 	      break;
268 
269 	    case KEY_UP:
270 	      focus--;
271 	      break;
272 	    case KEY_DOWN:
273 	      focus++;
274 	      break;
275 	    }
276 	  break;
277 
278 	case 1:		/* rmslengthstr */
279 	  stringinput_stdkeys (in_ch, &rmslengthstr);
280 	  switch (in_ch)
281 	    {
282 	    case KEY_ENTER:
283 	    case 13:
284 	      i = sscanf (rmslengthstr.string, "%li", &helplong);
285 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
286 		error_window ("A whole, odd number, greater than 0, must \
287 be specified.");
288 	      else
289 		focus++;
290 	      break;
291 
292 	    case KEY_UP:
293 	      focus--;
294 	      break;
295 	    case KEY_DOWN:
296 	      focus++;
297 	      break;
298 	    }
299 	  break;
300 
301 	case 2:		/* rmflengthstr */
302 	  stringinput_stdkeys (in_ch, &rmflengthstr);
303 	  switch (in_ch)
304 	    {
305 	    case KEY_ENTER:
306 	    case 13:
307 	      i = sscanf (rmflengthstr.string, "%li", &helplong);
308 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
309 		error_window ("A whole, odd number, greater than 0, must \
310 be specified.");
311 	      else
312 		focus++;
313 	      break;
314 
315 	    case KEY_UP:
316 	      focus--;
317 	      break;
318 	    case KEY_DOWN:
319 	      focus++;
320 	      break;
321 	    }
322 	  break;
323 
324 	case 3:		/* decimatestr */
325 	  stringinput_stdkeys (in_ch, &decimatestr);
326 	  switch (in_ch)
327 	    {
328 	    case KEY_ENTER:
329 	    case 13:
330 	      i = sscanf (decimatestr.string, "%li", &helplong);
331 	      if (i < 1 || helplong < 1)
332 		error_window ("A whole number, greater than 0, must \
333 be specified.");
334 	      else
335 		focus++;
336 	      break;
337 
338 	    case KEY_UP:
339 	      focus--;
340 	      break;
341 	    case KEY_DOWN:
342 	      focus++;
343 	      break;
344 	    }
345 	  break;
346 
347 	case 4:		/* thresholdstr */
348 	  stringinput_stdkeys (in_ch, &thresholdstr);
349 	  switch (in_ch)
350 	    {
351 	    case KEY_ENTER:
352 	    case 13:
353 	      i = sscanf (thresholdstr.string, "%li", &helplong);
354 	      if (i < 1 || helplong < 1000)
355 		error_window ("A whole number, greater than 1000, must \
356 be specified.");
357 	      else
358 		focus = 7;
359 	      break;
360 
361 	    case KEY_UP:
362 	      focus--;
363 	      break;
364 	    case KEY_DOWN:
365 	      focus++;
366 	      break;
367 	    }
368 	  break;
369 
370 	case 5:		/* Cancel */
371 	  switch (in_ch)
372 	    {
373 	    case KEY_ENTER:
374 	    case 13:
375 	      dont_stop = FALSE;
376 	      break;
377 
378 	    case KEY_LEFT:
379 	    case KEY_UP:
380 	      focus--;
381 	      break;
382 	    case KEY_RIGHT:
383 	    case KEY_DOWN:
384 	      focus++;
385 	      break;
386 	    }
387 	  break;
388 
389 	case 6:		/* Defaults */
390 	  switch (in_ch)
391 	    {
392 	    case KEY_ENTER:
393 	    case 13:
394 	      if (yesno_window ("Restore default parameters?", " Yes ",
395 				" No ", 0))
396 		{
397 		  cond_median_param_defaults (parampointer);
398 		  dont_stop = FALSE;
399 		}
400 	      break;
401 
402 	    case KEY_LEFT:
403 	    case KEY_UP:
404 	      focus--;
405 	      break;
406 	    case KEY_RIGHT:
407 	    case KEY_DOWN:
408 	      focus++;
409 	      break;
410 	    }
411 	  break;
412 
413 	case 7:		/* OK */
414 	  switch (in_ch)
415 	    {
416 	    case KEY_ENTER:
417 	    case 13:
418 
419 	      i = sscanf (medlengthstr.string, "%li", &helplong);
420 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
421 		{
422 		  error_window ("A whole, odd number, greater than 0, must \
423 be specified as median length.");
424 		  medlengthstr.cursorpos =
425 		    strlen (medlengthstr.string);
426 		  focus = 0;
427 		  break;
428 		}
429 
430 	      parampointer->prelength1 = (helplong - 1) / 2;
431 	      parampointer->postlength1 = (helplong - 1) / 2;
432 
433 	      i = sscanf (rmslengthstr.string, "%li", &helplong);
434 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
435 		{
436 		  error_window ("A whole, odd number, greater than 0, must \
437 be specified as RMS length.");
438 		  rmslengthstr.cursorpos =
439 		    strlen (rmslengthstr.string);
440 		  focus = 1;
441 		  break;
442 		}
443 
444 	      parampointer->prelength2 = (helplong - 1) / 2;
445 	      parampointer->postlength2 = (helplong - 1) / 2;
446 
447 	      i = sscanf (rmflengthstr.string, "%li", &helplong);
448 	      if (i < 1 || helplong < 1 || helplong % 2 == 0)
449 		{
450 		  error_window ("A whole, odd number, greater than 0, must \
451 be specified as length of the recursive median.");
452 		  rmflengthstr.cursorpos =
453 		    strlen (rmflengthstr.string);
454 		  focus = 2;
455 		  break;
456 		}
457 
458 	      parampointer->prelength3 = (helplong - 1) / 2;
459 	      parampointer->postlength3 = (helplong - 1) / 2;
460 
461 	      i = sscanf (decimatestr.string, "%li", &helplong);
462 	      if (i < 1 || helplong < 1)
463 		{
464 		  error_window ("A whole number, greater than 0, must \
465 be specified as decimation factor.");
466 		  decimatestr.cursorpos =
467 		    strlen (decimatestr.string);
468 		  focus = 3;
469 		  break;
470 		}
471 
472 	      parampointer->int1 = helplong;
473 
474 	      i = sscanf (thresholdstr.string, "%li", &helplong);
475 	      if (i < 1 || helplong < 1000)
476 		{
477 		  error_window ("A whole number, greater than 1000, must \
478 be specified as threshold.");
479 		  thresholdstr.cursorpos =
480 		    strlen (thresholdstr.string);
481 		  focus = 4;
482 		  break;
483 		}
484 
485 	      parampointer->long1 = helplong;
486 
487 	      dont_stop = FALSE;
488 	      break;
489 
490 	    case KEY_LEFT:
491 	    case KEY_UP:
492 	      focus--;
493 	      break;
494 	    case KEY_RIGHT:
495 	    case KEY_DOWN:
496 	      focus++;
497 	      break;
498 	    }
499 	  break;
500 	}
501 
502       if (in_ch == 9)		/* TAB */
503 	focus++;
504 
505       if (in_ch == 27)
506 	dont_stop = FALSE;
507 
508       if (focus > 7)
509 	focus = 0;
510       if (focus < 0)
511 	focus = 7;
512     }
513   while (dont_stop);
514 
515   free (medlengthstr.string);
516   free (rmslengthstr.string);
517   free (rmflengthstr.string);
518   free (decimatestr.string);
519   free (thresholdstr.string);
520 }
521 #endif /* SWIG */
522 
523 void
init_cond_median_filter(int filterno,parampointer_t parampointer)524 init_cond_median_filter (int filterno, parampointer_t parampointer)
525 {
526   long total_post;
527   long total_pre;
528 
529   total_post = parampointer->postlength1;
530   if (parampointer->postlength2 > total_post)
531     total_post = parampointer->postlength2;
532 
533   total_pre = parampointer->prelength1;
534   if (parampointer->prelength2 +
535       parampointer->prelength3 * parampointer->int1 + 1 > total_pre)
536     total_pre = parampointer->prelength2 +
537       parampointer->prelength3 * parampointer->int1 + 1;
538 
539   parampointer->buffer = init_buffer (total_post, total_pre);
540   parampointer->buffer2 = init_buffer (parampointer->postlength2,
541 				       parampointer->prelength2);
542   parampointer->buffer3 = init_buffer (parampointer->postlength3,
543 			     parampointer->prelength3 * parampointer->int1);
544 
545   parampointer->filterno = filterno;
546 }
547 
548 
549 void
delete_cond_median_filter(parampointer_t parampointer)550 delete_cond_median_filter (parampointer_t parampointer)
551 {
552   delete_buffer (&parampointer->buffer);
553   delete_buffer (&parampointer->buffer2);
554   delete_buffer (&parampointer->buffer3);
555 }
556 
557 
558 sample_t
cond_median_highpass(long offset,long offset_zero,parampointer_t parampointer)559 cond_median_highpass (long offset, long offset_zero,
560 		      parampointer_t parampointer)
561 {
562   sample_t sample;
563   longsample_t sum;
564 
565   offset += offset_zero;	/* middle for highpass filter in
566 				   'big buffer' */
567   sum.left = 0;
568   sum.right = 0;
569 
570 #define notTEST_DAVE_PLATT
571 #ifndef TEST_DAVE_PLATT
572   sample = get_from_buffer (&parampointer->buffer, offset - 1);
573   sum.left += sample.left;
574   sum.right += sample.right;
575   sample = get_from_buffer (&parampointer->buffer, offset);
576   sum.left -= 2 * (long) sample.left;
577   sum.right -= 2 * (long) sample.right;
578   sample = get_from_buffer (&parampointer->buffer, offset + 1);
579   sum.left += sample.left;
580   sum.right += sample.right;
581 
582   sum.left /= 4;
583   sum.right /= 4;
584 #else
585   /* Testing, suggested by Dave Platt. Invert phase of one channel, then
586      do tick detection using the sum signal. This is because most ticks
587      are out-of-phase signals. I've not really tested this - it might
588      require other settings for thresholds etc. */
589   sample = get_from_buffer (&parampointer->buffer, offset - 1);
590   sum.left += sample.left;
591   sum.left -= sample.right;
592   sample = get_from_buffer (&parampointer->buffer, offset);
593   sum.left -= 2 * (long) sample.left;
594   sum.left += 2 * (long) sample.right;
595   sample = get_from_buffer (&parampointer->buffer, offset + 1);
596   sum.left += sample.left;
597   sum.left -= sample.right;
598 
599   /* just in case L/R: 32000/-32000 -32000/32000 32000/-32000 : */
600   sum.left /= 8;
601   sum.right = sum.left;
602 #endif /* TEST_DAVE_PLATT */
603 
604   sample.left = sum.left;
605   sample.right = sum.right;
606 
607   return sample;
608 }
609 
610 fillfuncpointer_t cond_median_highpass_pointer = cond_median_highpass;
611 
612 sample_t
cond_median_rms(long offset,long offset_zero,parampointer_t parampointer)613 cond_median_rms (long offset, long offset_zero,
614 		 parampointer_t parampointer)
615 {
616   sample_t sample;
617   doublesample_t doublesample;
618   doublesample_t sum;
619   long i;
620 
621   advance_current_pos_custom (&parampointer->buffer2,
622 			      cond_median_highpass_pointer,
623 			      offset + offset_zero,
624 			      parampointer);
625 
626   sum.left = 0;
627   sum.right = 0;
628 
629   for (i = -parampointer->postlength2; i <= parampointer->prelength2;
630        i++)
631     {
632       sample = get_from_buffer (&parampointer->buffer2, i);
633       doublesample.left = sample.left;
634       doublesample.right = sample.right;
635       sum.left += doublesample.left * doublesample.left;
636       sum.right += doublesample.right * doublesample.right;
637     }
638 
639   sum.left /= (parampointer->postlength2 +
640 	       parampointer->prelength2 + 1);
641   sum.right /= (parampointer->postlength2 +
642 		parampointer->prelength2 + 1);
643 
644   sample.left = sqrt (sum.left + 1);
645   sample.right = sqrt (sum.right + 1);
646 
647   return sample;
648 }
649 
650 fillfuncpointer_t cond_median_rms_pointer = cond_median_rms;
651 
652 sample_t
653 #ifndef SWIG
cond_median_filter(parampointer_t parampointer)654 cond_median_filter (parampointer_t parampointer)
655 #else
656 cond_median_filter (parampointer_t parampointer, int *filter_type)
657 #endif
658 {
659   sample_t sample;
660   sample_t w_t;
661   sample_t b_t;
662   sample_t returnval;
663   signed short list1[parampointer->postlength3 +
664 		     parampointer->prelength3 * parampointer->int1 + 1];
665   signed short list2[parampointer->postlength3 +
666 		     parampointer->prelength3 * parampointer->int1 + 1];
667   signed short list3[parampointer->postlength1 + parampointer->prelength1 + 1];
668   long i, j;
669 
670 #ifndef SWIG
671   advance_current_pos (&parampointer->buffer, parampointer->filterno);
672 #else
673   advance_current_pos (&parampointer->buffer, parampointer->filterno, filter_type);
674 #endif
675 
676   advance_current_pos_custom (&parampointer->buffer3,
677 			      cond_median_rms_pointer,
678 			      0,
679 			      parampointer);
680 
681   w_t = get_from_buffer (&parampointer->buffer3, 0);
682 
683   /* The RMF Filter */
684 
685   for (i = 0; i < parampointer->postlength3; i++)
686     {
687       sample = get_from_buffer (&parampointer->buffer3,
688 				i - parampointer->postlength3);
689       list1[i] = sample.left;
690       list2[i] = sample.right;
691     }
692 
693   j = i;
694 
695   for (; i <= parampointer->postlength3 +
696        parampointer->prelength3 * parampointer->int1;
697        i += parampointer->int1)
698     {
699       sample = get_from_buffer (&parampointer->buffer3,
700 				i - parampointer->postlength3);
701       list1[j] = sample.left;
702       list2[j] = sample.right;
703       j++;
704     }
705 
706   b_t.left = median (list1, j);
707   b_t.right = median (list2, j);
708 
709   put_in_buffer (&parampointer->buffer3, 0, b_t);
710 
711 #ifdef VIEW_INTERNALS
712 
713   returnval.left = b_t.left * 10;
714 
715   if (
716        (labs (w_t.left - b_t.left) * 1000)
717        /
718        b_t.left > parampointer->long1)
719     returnval.right = 2000;
720   else
721     returnval.right = 0;
722 
723 #else /* not VIEW_INTERNALS */
724 
725   returnval = get_from_buffer (&parampointer->buffer, 0);
726 
727   /* Median Filters - if necessary */
728 
729   if (
730        (labs (w_t.left - b_t.left) * 1000)
731        /
732        b_t.left > parampointer->long1)
733     {
734       for (i = 0; i <= parampointer->postlength1 +
735 	   parampointer->prelength1; i++)
736 	list3[i] = get_from_buffer (&parampointer->buffer,
737 				    i - parampointer->postlength1).left;
738 
739       returnval.left = median (list3, parampointer->postlength1 +
740 			       parampointer->prelength1 + 1);
741     }
742 
743   if (
744        (labs (w_t.right - b_t.right) * 1000)
745        /
746        b_t.right > parampointer->long1)
747     {
748       for (i = 0; i <= parampointer->postlength1 +
749 	   parampointer->prelength1; i++)
750 	list3[i] = get_from_buffer (&parampointer->buffer,
751 				    i - parampointer->postlength1).right;
752 
753       returnval.right = median (list3, parampointer->postlength1 +
754 				parampointer->prelength1 + 1);
755     }
756 
757 #endif /* VIEW_INTERNALS */
758 
759   return returnval;
760 }
761