/* Copyright 2017 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include "dcblock.h" #define RAMP_TIME_MS 20 struct dcblock { float R; float x_prev; float y_prev; float ramp_factor; float ramp_increment; int initialized; }; struct dcblock *dcblock_new(float R, unsigned long sample_rate) { struct dcblock *dcblock = (struct dcblock *)calloc(1, sizeof(*dcblock)); dcblock->R = R; dcblock->ramp_increment = 1000. / (float)(RAMP_TIME_MS * sample_rate); return dcblock; } void dcblock_free(struct dcblock *dcblock) { free(dcblock); } /* This is the prototype of the processing loop. */ void dcblock_process(struct dcblock *dcblock, float *data, int count) { int n; float x_prev = dcblock->x_prev; float y_prev = dcblock->y_prev; float R = dcblock->R; if (!dcblock->initialized) { x_prev = data[0]; dcblock->initialized = 1; } for (n = 0; n < count; n++) { float x = data[n]; float d = x - x_prev + R * y_prev; y_prev = d; x_prev = x; /* * It takes a while for this DC-block filter to completely * filter out a large DC-offset, so apply a mix-in ramp to * avoid any residual jump discontinuities that can lead to * "pop" during capture. */ if (dcblock->ramp_factor < 1.0) { d *= dcblock->ramp_factor; dcblock->ramp_factor += dcblock->ramp_increment; } data[n] = d; } dcblock->x_prev = x_prev; dcblock->y_prev = y_prev; }