Вопрос скорее всего к 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(); }
Any suggestions?
|