Вопрос скорее всего к Rst7, но если кто-то еще сможет помочь, буду очень признателен.
Имеется такой код, сделанный в Keil uVision для LPC1759, но я не понимаю, почему результаты свертки через FFT получаются неправильные. Перепроверял 500 раз все. По аналогичному алгоритму делал прогу на C++ в Билдере и все работало,а тут... Раскладывается в спектр и собирается обратно правильно. Каждый блок продлен нулями до длины, превышающей их сумму минус 1, что необходимо для вычисления линейной свертки.
Причем, если в импульсе (условно) установить только одну какую-то точку, а все остальные нули, то считается правильно. Если больше одной, отличной от нуля, начинается лажа.
Все реализовано на функциях из официальной либы от NXP - DSPLib.
Вот, собственно, код:
#include <system_lpc17xx.c>
#include <LPC17xx.H>
#include "arm_math.h"
#include "math_helper.h"
float32_t testInputA_f32[64] =
{
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, //один
23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609, //входной блок
32767, 32609, 32137, 31356, 30272, 28897, 27244, 25329,
23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211,
0, -3211, -6392, -9511, -12539, -15446, -18204, -20787,
-23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609,
-32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329,
-23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211
};
float32_t testInputB_f32[64] =
{
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, //"импульс"
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
};
#define MAX_BLOCKSIZE 128
float32_t Ak[MAX_BLOCKSIZE]; //входные
float32_t Bk[MAX_BLOCKSIZE]; //буферы;
float32_t AxB[MAX_BLOCKSIZE * 2]; //выходной буфер;
float32_t conv[128]; //референс
void up(void)
{
LPC_GPIO1->FIODIR |= 1<<0;
}
void down(void)
{
LPC_GPIO1->FIODIR &= 0<<0;
}
//-------------------------------------------------------------------------------------
int32_t main(void)
{
arm_cfft_radix4_instance_f32 cfft_instance; // объявляем аргументы функций
arm_cfft_radix4_instance_f32 cfft_instance_inv; // прямого и обратного БПФ
arm_cfft_radix4_instance_f32 *cfft_instance_ptr = //создаем
(arm_cfft_radix4_instance_f32*) &cfft_instance; //указатели
//на аргументы
arm_cfft_radix4_instance_f32 *cfft_instance_inv_ptr = //функций
(arm_cfft_radix4_instance_f32*) &cfft_instance_inv; //прямого и обратного БПФ
/* Заполняем входные буферы нулями*/
arm_fill_f32(0.0, Ak, MAX_BLOCKSIZE);
arm_fill_f32(0.0, Bk, MAX_BLOCKSIZE);
/* Копируем данные в половину длины каждого буфера*/
arm_copy_f32(testInputA_f32, Ak, MAX_BLOCKSIZE/2);
arm_copy_f32(testInputB_f32, Bk, MAX_BLOCKSIZE/2);
arm_conv_f32(Ak, 64, Bk, 64, conv); // для сравнения делаем свертку отдельной функцией
arm_cfft_radix4_init_f32(cfft_instance_ptr, 64, 0, 1); // Инициализируем
// прямое и обратное
arm_cfft_radix4_init_f32(cfft_instance_inv_ptr, 64, 1, 1); // БПФ
arm_cfft_radix4_f32(cfft_instance_ptr, Bk); // Делаем БПФ ядра
up();
arm_cfft_radix4_f32(cfft_instance_ptr, Ak); // Делаем БПФ данных
arm_cmplx_mult_cmplx_f32(Ak, Bk, AxB, MAX_BLOCKSIZE); // Комплексно перемножаем результаты
arm_cfft_radix4_f32(cfft_instance_inv_ptr, AxB); // Делаем обратное БПФ
down();
}
[size=11]Any suggestions?[/size]