Котельников с Найквистом говорят, что в исходном сигнале есть пики с частотами чуть ли не в десятки кГц, если их аналогово не пофильтровали. И если искать максимумы, то такой пик запросто за максимум сойти может, а если предварительно http://caxapa.ru/639573.html
пофильтровать, то там может и никаких максимумов уже и не будет. Всякие варианты со скользящим средним, в частности предлагаемое "экспоненциально скользящее вреднее" (EMA) использовать по-моему очень плохо, т.к. в частотной области оно затухает с бесконечно длинным хвостом (который у FIR-фильтра и у обычного скользящего среднего хотя бы имеет ряд нулей и затухает быстрей). По ссылке в апплете (http://www.falstad.com/dfilter/) можно выбрать скользящее среднее (moving average) и посмотреть насколько он от FIR отличается (где за счет осмысленных, а не 1/0 коэффициентов, хвост получается быстро затухающим). Кроме того, автору нужно от постоянной составляющей избавиться. Фактически ему нужен полосовой (bandpass) фильтр. Можно вот здесь с коэффициентами вручную поиграться если нужен именно FIR: http://t-filter.engineerjs.com/ Например ввести: 0-100hz gain 0 (-20db), 300-500hz gain 1 (5db), 6000-4000hz gain 0 (-20db) и получить результат представленный ниже. Мне уже кажется, что БИХ (IIR) фильтр проще перемножений меньше...
#include "SampleFilter.h"
static int filter_taps[SAMPLEFILTER_TAP_NUM] = {
1901,
570,
507,
327,
33,
-351,
-795,
-1243,
-1640,
-1927,
-2054,
-1986,
-1709,
-1236,
-603,
129,
885,
1585,
2152,
2519,
2647,
2519,
2152,
1585,
885,
129,
-603,
-1236,
-1709,
-1986,
-2054,
-1927,
-1640,
-1243,
-795,
-351,
33,
327,
507,
570,
1901
};
void SampleFilter_init(SampleFilter* f) {
int i;
for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i)
f->history[i] = 0;
f->last_index = 0;
}
void SampleFilter_put(SampleFilter* f, int input) {
f->history[f->last_index++] = input;
if(f->last_index == SAMPLEFILTER_TAP_NUM)
f->last_index = 0;
}
int SampleFilter_get(SampleFilter* f) {
long long acc = 0;
int index = f->last_index, i;
for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) {
index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1;
acc += (long long)f->history[index] * filter_taps[i];
};
return acc >> 16;
}
SampleFilter.h Select all
#ifndef SAMPLEFILTER_H_
#define SAMPLEFILTER_H_
/*
FIR filter designed with
http://t-filter.appspot.com
sampling frequency: 8000 Hz
fixed point precision: 16 bits
* 0 Hz - 100 Hz
gain = 0
desired attenuation = -20 dB
actual attenuation = n/a
* 300 Hz - 500 Hz
gain = 1
desired ripple = 5 dB
actual ripple = n/a
* 600 Hz - 4000 Hz
gain = 0
desired attenuation = -20 dB
actual attenuation = n/a
*/
#define SAMPLEFILTER_TAP_NUM 41
typedef struct {
int history[SAMPLEFILTER_TAP_NUM];
unsigned int last_index;
} SampleFilter;
void SampleFilter_init(SampleFilter* f);
void SampleFilter_put(SampleFilter* f, int input);
int SampleFilter_get(SampleFilter* f);
#endif
[ZX]
пофильтровать, то там может и никаких максимумов уже и не будет. Всякие варианты со скользящим средним, в частности предлагаемое "экспоненциально скользящее вреднее" (EMA) использовать по-моему очень плохо, т.к. в частотной области оно затухает с бесконечно длинным хвостом (который у FIR-фильтра и у обычного скользящего среднего хотя бы имеет ряд нулей и затухает быстрей). По ссылке в апплете (http://www.falstad.com/dfilter/) можно выбрать скользящее среднее (moving average) и посмотреть насколько он от FIR отличается (где за счет осмысленных, а не 1/0 коэффициентов, хвост получается быстро затухающим). Кроме того, автору нужно от постоянной составляющей избавиться. Фактически ему нужен полосовой (bandpass) фильтр. Можно вот здесь с коэффициентами вручную поиграться если нужен именно FIR: http://t-filter.engineerjs.com/ Например ввести: 0-100hz gain 0 (-20db), 300-500hz gain 1 (5db), 6000-4000hz gain 0 (-20db) и получить результат представленный ниже. Мне уже кажется, что БИХ (IIR) фильтр проще перемножений меньше...
-
- За ссылки отдельное спасибо! Эта не та тема, в которой я силён, но 500 Гц сэмплирования 400Гц сигнала явно мало. С этим вы согласитесь? Dingo(288 знак., 29.12.2017 07:02 - 07:20)