Код
/**
* @brief Processing function for the floating-point FIR filter.
* @param[in] *S points to an instance of the floating-point FIR structure.
* @param[in] *pSrc points to the block of input data.
* @param[out] *pDst points to the block of output data.
* @param[in] blockSize number of samples to process.
* @return none.
*/
void arm_fir_f32(
const arm_fir_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
f32 означает тип данных. Количество передается в blockSize. Заглячнул в код CMSIS... когда увидел цикл,
Код
/* Copy numTaps number of values */
tapCnt = numTaps - 1u;
/* Copy data */
while(tapCnt > 0u)
{
*pStateCurnt++ = *pState++;
/* Decrement the loop counter */
tapCnt--;
}
Смотреть расхотелось навсегда...
Фильтр для своей работы в любом случае требует массива значений - предшествующих текущему моменту.
Вот такое использую в своих проектах:
Код
// Ограничение алгоритма генерации параметров фильтра - нечётное значение Ntap.
// Кроме того, для функций фильтрации с использованием симметрии коэффициентов, требуется кратность 2 половины Ntap
#define NtapValidate(n) ((unsigned) (n) / 4 * 4 + 1)
#define NtapCoeffs(n) ((unsigned) (n) / 2 + 1)
#define Ntap_rx_AUDIO NtapValidate(241) // single samples, floating-point implementation
static FLOAT_T FIRCoef_rx_AUDIO [NPROF] [NtapCoeffs(Ntap_rx_AUDIO)] = { { 0 }, { 0 } };
static FLOAT_T FIRScale_rx_AUDIO [NPROF] = { 1, 1 };
static FLOAT_T filter_fir_rx_AUDIO(FLOAT_T NewSample)
{
const FLOAT_T * const k = FIRCoef_rx_AUDIO [gwprof];
enum { Ntap = Ntap_rx_AUDIO, NtapHalf = Ntap / 2 };
// буфер с сохраненными значениями сэмплов
static FLOAT_T x [Ntap * 2] = { 0, };
static uint_fast16_t fir_head = 0;
// shift the old samples
fir_head = (fir_head == 0) ? (Ntap - 1) : (fir_head - 1);
x [fir_head] = x [fir_head + Ntap] = NewSample;
uint_fast16_t bh = fir_head + NtapHalf; // Начало обрабатываемой части буфера
uint_fast16_t bt = bh; // Позиция за концом обрабатываемого буфера
// Calculate the new output
uint_fast16_t n = NtapHalf;
// Выборка в середине буфера
register FLOAT_T v = k [NtapHalf] * x [bh]; // sample at middle of buffer
do
{
{
const FLOAT_T kv = k [-- n];
v += kv * x [-- bh];
v += kv * x [++ bt];
}
{
const FLOAT_T kv = k [-- n];
v += kv * x [-- bh];
v += kv * x [++ bt];
}
}
while (n != 0);
// Обеспечиваем масштабирование к ранее расчитанному усилению фильтра (1.0)
return v * FIRScale_rx_AUDIO [gwprof];
}
Перевести на целочисленный вариант легко. Придется накапливать в 64 битах (для q31), при использовании результата учесть разрядность рассчитанных коэффициентов
Цитата
ругается на коэффициенты. Так как они имеют вид:
-0.0085006295830239147,
-0.039315452455814658,
0.020190437531132147,
0.0076176048595180471
Множите перед использованием на 32768 (в случае Q15). Результат фильтрации делите на 32768
Библиотечная функция arm_fir_fast_q15 использует SIMD инструкции для работы с парами 16-ти битных чисел за одну операцию, данные для фильтрации можете располагать как в моей функции (массив двойной длинны, без необходимости копирования массива данных для сдвига).
Сообщение отредактировал Genadi Zawidowski - Jul 1 2015, 19:57