43 #include "array_smoother.h"
44 #include "EST_cutils.h"
48 #define MODULE "array_smoother"
50 float median (
int *counter,
float valin,
float valbuf[],
int lmed,
int mmed);
51 float hanning (
int *counter,
float valin,
float valhan[],
float win_coeff[],
53 void mk_window_coeffs (
int length,
float win_coeff[]);
57 void array_smoother (
float *p_array,
int arraylen,
struct Ms_Op *ms)
59 int i, j, mid1, mid2 = 0, filler, nloops;
60 int C1, C2 = 0, C3 = 0, C4 = 0, c1, c2, c3, c4;
61 int delay, delx = 0, dely = 0;
65 float xdel[2 * MAX_LEN - 2], ydel[2 * MAX_LEN - 2];
66 float medbuf1[MAX_LEN], medbuf2[MAX_LEN];
67 float hanbuf1[MAX_LEN], hanbuf2[MAX_LEN], win_coeffs[MAX_LEN];
68 float medval1, medval2, hanval1, hanval2, zatn;
70 inarray =
new float[arraylen];
71 for (i = 0; i < arraylen; ++i)
72 inarray[i] = p_array[i];
80 mk_window_coeffs (ms->window_length, win_coeffs);
82 mid1 = ms->first_median / 2;
83 C1 = delay = ms->first_median - 1;
84 if (ms->apply_hanning)
86 C2 = ms->window_length - 1;
87 delay = ms->first_median + ms->window_length - 2;
89 if (ms->smooth_double) {
90 mid2 = ms->second_median / 2;
91 C3 = ms->second_median - 1;
92 if (!ms->apply_hanning) {
93 delx = ms->first_median;
94 dely = ms->second_median;
97 C4 = ms->window_length - 1;
98 delx = ms->first_median + ms->window_length - 1;
99 dely = ms->second_median + ms->window_length - 1;
101 delay = delx + dely - 2;
108 if (!ms->extrapolate) {
110 for (i = 0; i < delay / 2; i++)
111 p_array[out++] = ms->breaker;
118 nloops = arraylen + delay;
121 for (j = 0; j < nloops; j++)
123 if (j < filler || j >= nloops - filler)
126 input = inarray[in++];
129 if (ms->smooth_double) {
130 for (i = delx - 1; i > 0; i--)
131 xdel[i] = xdel[i - 1];
136 medval1 = median (&c1, input, medbuf1, ms->first_median, mid1);
142 if (ms->apply_hanning)
144 hanval1 = hanning (&c2, medval1, hanbuf1, win_coeffs, ms);
151 if (ms->smooth_double)
154 if (output != ms->breaker && xdel[delx - 1]
156 zatn = xdel[delx - 1] - output;
160 for (i = dely - 1; i > 0; i--)
161 ydel[i] = ydel[i - 1];
164 medval2 = median (&c3, zatn, medbuf2,
165 ms->second_median, mid2);
170 if (ms->apply_hanning) {
171 hanval2 = hanning (&c4, medval2, hanbuf2,
178 if (output != ms->breaker && ydel[dely - 1]
180 output += ydel[dely - 1];
182 output = ms->breaker;
188 p_array[out++] = output;
191 if (!ms->extrapolate)
192 for (i = 0; i < delay / 2; i++)
193 p_array[out++] = ms->breaker;
198 float median (
int *counter,
float valin,
float valbuf[],
int lmed,
int mmed)
201 float tmp, filmed[MAX_LEN];
203 for (i = lmed - 1; i > 0; i--)
204 valbuf[i] = valbuf[i - 1];
216 for (i = 0; i < lmed; i++)
217 filmed[i] = valbuf[i];
219 for (j = lmed - 1; j > 0; j--)
220 for (i = 0; i < j; i++)
221 if (filmed[i] > filmed[i + 1])
224 filmed[i + 1] = filmed[i];
227 return (filmed[mmed]);
232 #define TWO_PI 6.28318530717958647698
234 void mk_window_coeffs (
int length,
float win_coeff[])
239 for (i = 0; i < length; i++) {
240 x = TWO_PI * (i + 1.0) / (length + 1.0);
241 win_coeff[i] = (1.0 - (float) cos (x)) / (length + 1.0);
246 float hanning (
int *counter,
float valin,
float valhan[],
float win_coeff[],
250 float valout = 0.0, weight[MAX_LEN];
252 for (i = par->window_length - 1; i > 0; i--)
253 valhan[i] = valhan[i - 1];
261 for (i = 0; i < par->window_length; i++)
262 if (valhan[i] == par->breaker)
265 for (i = 0; i < par->window_length; i++)
266 valout += valhan[i] * win_coeff[i];
267 else if (k <= par->window_length / 2 && par->extrapolate) {
268 mk_window_coeffs (par->window_length - k, weight);
269 for (i = 0, j = 0; i < par->window_length; i++)
270 if (valhan[i] != par->breaker)
271 valout += valhan[i] * weight[j++];
274 valout = par->breaker;
280 void initialise_parameters (
struct Ms_Op *p_par)
282 p_par->smooth_double = 0;
283 p_par->apply_hanning = 0;
284 p_par->extrapolate = 0;
285 p_par->window_length = DEFAULT_WLEN;
286 p_par->first_median = DEFAULT_MED_1;
287 p_par->second_median = DEFAULT_MED_2;
293 ms->smooth_double = FALSE;
294 ms->apply_hanning = TRUE;
295 ms->extrapolate = TRUE;
296 ms->first_median = 11;
297 ms->second_median = 1;
298 ms->window_length = 7;