news 2026/7/31 3:39:08

simple_fft.c

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
simple_fft.c

/**
******************************************************************************
* @file simple_fft.c
* @brief 简单 radix-2 Cooley-Tukey FFT 实现,无第三方算法库。
******************************************************************************
*/

#include "simple_fft.h"

#define SIMPLE_FFT_MAX_LENGTH 256U

static uint8_t SimpleFFT_IsPowerOfTwo(uint16_t value);
static uint16_t SimpleFFT_ReverseBits(uint16_t value, uint8_t bit_count);
static uint8_t SimpleFFT_Log2(uint16_t value);

uint8_t SimpleFFT_ForwardReal(const float *input, SimpleFFT_Complex_t *output, uint16_t length)
{
uint16_t i;
uint16_t block_size;
uint8_t bits;

if ((input == 0) || (output == 0) || (length > SIMPLE_FFT_MAX_LENGTH) ||
(SimpleFFT_IsPowerOfTwo(length) == 0U))
{
return 0U;
}

/* FFT 首先做位倒序重排:输入第 i 个样本写入输出的 bit_reverse(i) 位置。 */
bits = SimpleFFT_Log2(length);
for (i = 0U; i < length; i++)
{
uint16_t reversed = SimpleFFT_ReverseBits(i, bits);
output[reversed].real = input[i];
output[reversed].imag = 0.0f; /* 实数输入的虚部固定为 0。 */
}

/* 每一级把两个小 DFT 合成一个更大的 DFT;2 -> 4 -> ... -> length。 */
for (block_size = 2U; block_size <= length; block_size <<= 1U)
{
float step_real;
float step_imag;
uint16_t half = (uint16_t)(block_size >> 1U);
uint16_t start;
uint16_t j;

/*
* 本级旋转因子 exp(-j*2*pi/block_size)。只支持最大 256 点,
* 所有需要的 cos/sin 常量均列出,避免调用 math 库。
*/
switch (block_size)
{
case 2U: step_real = -1.0f; step_imag = 0.0f; break;
case 4U: step_real = 0.0f; step_imag = -1.0f; break;
case 8U: step_real = 0.70710678f; step_imag = -0.70710678f; break;
case 16U: step_real = 0.92387953f; step_imag = -0.38268343f; break;
case 32U: step_real = 0.98078528f; step_imag = -0.19509032f; break;
case 64U: step_real = 0.99518473f; step_imag = -0.09801714f; break;
case 128U: step_real = 0.99879546f; step_imag = -0.04906767f; break;
case 256U: step_real = 0.99969882f; step_imag = -0.02454123f; break;
default: return 0U;
}

for (start = 0U; start < length; start = (uint16_t)(start + block_size))
{
float w_real = 1.0f;
float w_imag = 0.0f;

for (j = 0U; j < half; j++)
{
uint16_t top = (uint16_t)(start + j);
uint16_t bottom = (uint16_t)(top + half);
float t_real = w_real * output[bottom].real - w_imag * output[bottom].imag;
float t_imag = w_real * output[bottom].imag + w_imag * output[bottom].real;
float top_real = output[top].real;
float top_imag = output[top].imag;
float next_w_real;

output[top].real = top_real + t_real;
output[top].imag = top_imag + t_imag;
output[bottom].real = top_real - t_real;
output[bottom].imag = top_imag - t_imag;

/* w = w * step,得到本级下一个蝶形运算的旋转因子。 */
next_w_real = w_real * step_real - w_imag * step_imag;
w_imag = w_real * step_imag + w_imag * step_real;
w_real = next_w_real;
}
}
}
return 1U;
}

float SimpleFFT_GetBinEnergy(const SimpleFFT_Complex_t *spectrum, uint16_t bin)
{
if (spectrum == 0)
{
return 0.0f;
}
return spectrum[bin].real * spectrum[bin].real + spectrum[bin].imag * spectrum[bin].imag;
}

static uint8_t SimpleFFT_IsPowerOfTwo(uint16_t value)
{
return ((value >= 2U) && ((value & (uint16_t)(value - 1U)) == 0U)) ? 1U : 0U;
}

static uint8_t SimpleFFT_Log2(uint16_t value)
{
uint8_t bits = 0U;
while (value > 1U)
{
value >>= 1U;
bits++;
}
return bits;
}

static uint16_t SimpleFFT_ReverseBits(uint16_t value, uint8_t bit_count)
{
uint16_t result = 0U;
while (bit_count > 0U)
{
result = (uint16_t)((result << 1U) | (value & 1U));
value >>= 1U;
bit_count--;
}
return result;
}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 3:36:01

Python 爬虫练习

学习Python有一段时间了&#xff0c;今天来练习一下爬虫。1.确认网站及关键元素2.程序开头和库的导入3.抓取网页4.解析页面5.创建文档并保留数据6.结果展示

作者头像 李华
网站建设 2026/7/31 3:35:52

GEO测评解析:生成式AI内容质量优化指南

1. 项目背景与核心概念2026响课GEO测评是一项针对生成式引擎优化&#xff08;Generative Engine Optimization&#xff09;专业能力的评估体系。这个测评项目源于当前内容生成技术爆发式发展背景下&#xff0c;对AI生成内容质量管控的迫切需求。简单来说&#xff0c;就是给各类…

作者头像 李华
网站建设 2026/7/31 3:35:03

Java 1.8核心特性与开发环境搭建指南

1. Java 1.8 学习路线与核心特性概览Java 1.8&#xff08;又称Java 8&#xff09;是Oracle在2014年发布的重要版本&#xff0c;它引入了诸多革命性特性&#xff0c;彻底改变了Java的编程范式。对于初学者而言&#xff0c;这个版本既是学习Java的最佳起点&#xff0c;也是面试和…

作者头像 李华
网站建设 2026/7/31 3:26:07

终极浏览器分屏解决方案:Tab-Resize扩展完全指南

终极浏览器分屏解决方案&#xff1a;Tab-Resize扩展完全指南 【免费下载链接】tab-resize Split Screen made easy. Resize the CURRENT tab and tabs to the RIGHT into layouts on separate Windows. w/ Multi-monitor Support 项目地址: https://gitcode.com/gh_mirrors/t…

作者头像 李华
网站建设 2026/7/31 3:25:11

京东惠采3C事业部入驻指南:企业采购平台运营与资质攻略

京东惠采3C事业部入驻全攻略&#xff1a;从申请到接单的完整指南在当前的电商采购市场中&#xff0c;企业采购正逐渐从传统的线下模式转向线上平台化采购。京东惠采作为京东集团面向企业客户推出的专属采购平台&#xff0c;为3C数码类目的商家提供了巨大的商机。特别是3C事业部…

作者头像 李华
网站建设 2026/7/31 3:24:58

硬盘接口与协议全解析:从SATA到NVMe,如何选择与优化存储性能

1. 从“插口”到“高速公路”&#xff1a;硬盘接口与协议的本质刚接触电脑硬件的朋友&#xff0c;常常会被硬盘的接口和协议搞得一头雾水。SATA、M.2、NVMe、PCIe……这些名词听起来既熟悉又陌生。你可能知道要买固态硬盘&#xff0c;但面对主板上形态各异的插槽和商品页面上琳…

作者头像 李华