+ char filter_buf[MAX_NAME_SIZE];
+ int num_fields;
+ char* cursor;
+ int window_size = 0;
+
+ /* By default, don't apply filtering */
+ sensor[s].filter_type = FILTER_TYPE_NONE;
+
+ /* Restrict filtering to a few sensor types for now */
+ switch (sensor[s].type) {
+ case SENSOR_TYPE_ACCELEROMETER:
+ case SENSOR_TYPE_GYROSCOPE:
+ case SENSOR_TYPE_MAGNETIC_FIELD:
+ num_fields = 3 /* x,y,z */;
+ break;
+
+ default:
+ return; /* No filtering */
+ }
+
+ /* If noisy, start with default filter for sensor type */
+ if (sensor[s].quirks & QUIRK_NOISY)
+ switch (sensor[s].type) {
+ case SENSOR_TYPE_GYROSCOPE:
+ sensor[s].filter_type = FILTER_TYPE_MEDIAN;
+ break;
+
+ case SENSOR_TYPE_MAGNETIC_FIELD:
+ sensor[s].filter_type = FILTER_TYPE_MOVING_AVERAGE;
+ break;
+ }
+
+ /* Use whatever was specified if there's an explicit configuration choice for this sensor */
+
+ filter_buf[0] = '\0';
+ sensor_get_st_prop(s, "filter", filter_buf);
+
+ cursor = strstr(filter_buf, "median");
+ if (cursor)
+ sensor[s].filter_type = FILTER_TYPE_MEDIAN;
+ else {
+ cursor = strstr(filter_buf, "average");
+ if (cursor)
+ sensor[s].filter_type = FILTER_TYPE_MOVING_AVERAGE;
+ }
+
+ /* Check if an integer is part of the string, and use it as window size */
+ if (cursor) {
+ while (*cursor && !isdigit(*cursor))
+ cursor++;
+
+ if (*cursor)
+ window_size = atoi(cursor);
+ }
+
+ switch (sensor[s].filter_type) {
+
+ case FILTER_TYPE_MEDIAN:
+ denoise_median_init(s, num_fields, window_size ? window_size : 5);
+ break;
+
+ case FILTER_TYPE_MOVING_AVERAGE:
+ denoise_average_init(s, num_fields, window_size ? window_size: 20);