双 {MOD}点阵做的FFT音乐频谱显示(类似千千静听效果)

2019-12-08 14:40发布

data/attach/1912/fstnl7vmjpillcd6wvcwa6gh0v0fwhiy.jpgdata/attach/1912/xycgk0pp1iifur4b8t39kx13ujt0lupn.jpgdata/attach/1912/alb57hkf32hrauz5kf9urot9iptnp4t8.jpgdata/attach/1912/1ijfir3vttegdlvh448vk9e8lt8wjqwg.jpgdata/attach/1912/z1isv15deg1n49f6tl2x29v4kx5knnax.jpgdata/attach/1912/51e5xfz4v3vlrklqfri21tg5gbr4mgze.jpgdata/attach/1912/bivjgvcafn8caj57lnsbjqoj6fspoxhv.jpgdata/attach/1912/4o52bngz8ivnatkoher0eftq8eigp7e2.jpgdata/attach/1912/ppclzlcsip2amd9u8nup56r0rvfdz5ef.jpgdata/attach/1912/omloqxo7gq4ayvh2r5q8d8rr8o5ghu4m.jpgdata/attach/1912/kqlhj5b329llg3mxsqdh2hhbzph9uo0t.jpgdata/attach/1912/vbf1uzb49zicz3acrjexxa4vbrl31396.jpgdata/attach/1912/kk1pxkk22i33x276qfopkx1ra3mneary.jpgdata/attach/1912/z59lwtifpuhndi8vnsaxd8o6207pqt4l.jpgdata/attach/1912/iwoqi0aoy9w2ipohqedged0x09ib1kqx.jpg 前阵子做功放,郁闷,问题一大堆,还好MCU部分没问题,做板时考虑了我的点阵驱动,所以郁闷之余,先玩玩点阵,把几年前的频谱显示移植了一下,之前用mega8做的,才64点的FFT,点阵也很少,才三个.现在用stm32,又有了64*32的点阵,所以把那个移植过来,应该效果不错.
废话不说了,看效果:
采样率是43.65Khz,做512点FFT,单位频率为85.225Hz.

(原文件名:1Khz正弦波2(千千静听).jpg)


(原文件名:1Khz正弦波2.jpg)


(原文件名:1Khz正弦波3.jpg)


(原文件名:1Khz正弦波(千千静听).jpg)


(原文件名:1Khz正弦波.jpg)


(原文件名:播放音乐1.jpg)


(原文件名:播放音乐2.jpg)


(原文件名:播放音乐3.jpg)


(原文件名:播放音乐4.jpg)


(原文件名:播放音乐(千千静听).jpg)


(原文件名:对比1.jpg)


(原文件名:对比2.jpg)


(原文件名:对比3.jpg)


(原文件名:对比4.jpg)


(原文件名:对比.jpg)

视频效果:http://v.youku.com/v_show/id_XMTYwNDc2MjI4.html
http://v.youku.com/v_show/id_XMTYwNDY4OTEy.html
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
97条回答
liujun6037
2019-12-10 09:25
#include "fft.h"
#include "fft_tab.h"
  
//FFT 频谱分析
//可以执行64/128/256/512/1024等点数的FFT计算
//所需要的变量:
//(FFT_N+1)*8 个字节左右
//正点原子@SUNTEK
//2010/3/23         
compx fftres[FFT_N]; //FFT数据段                                   
//m^n函数
u32 mypow(u8 m,u8 n)
{
        u32 result=1;         
        while(n--)result*=m;   
        return result;
}   
//快速傅里叶变换
//32/64/128/256/512/1024点的FFT
//STM32 计算1024点费时35.7ms左右@72M
//如果超频到120M,则时间只需要22ms左右了
//N:傅里叶变换的点数
//xin:输入数组大小为N+1
void FFT(compx *xin,u16 N)
{
        u16 f,m,LH,nm,i,k,j,L;
        u16 p;
        u16 le,B,ip;                      
        compx ws,t;
        LH=N/2;
        f=N;
        for(m=1;(f=f/2)!=1;m++);//求得M的值
        nm=N-2;   
        j=N/2;                  
        for(i=1;i<=nm;i++)//码位倒置
        {
                if(i<j){t=xin[j];xin[j]=xin;xin=t;}//码位家换
                k=LH;
                while(j>=k){j=j-k;k=k/2;}
                j=j+k;
        }   
        for(L=1;L<=m;L++) //fft  傅里叶变换
        {  
                le=mypow(2,L);//用自己定义的乘方函数,效率比库函数高很多.这里如果采用移位计算,效率更高.          
                B=le/2;                    
                for(j=0;j<=B-1;j++)
                {                          
                        p=mypow(2,m-L)*j;  //用自己定义的乘方函数,效率比库函数高很多.          
                        ws.real=cos_tab[p];
                        ws.imag=sin_tab[p];
                        for(i=j;i<=N-1;i=i+le)//遍历M级所有的碟形
                        {
                                ip=i+B;                 
                                //执行复数乘法
                                t.real=xin[ip].real*ws.real-xin[ip].imag*ws.imag;
                                t.imag=xin[ip].real*ws.imag+xin[ip].imag*ws.real;

                                xin[ip].real=xin.real-t.real;
                                xin[ip].imag=xin.imag-t.imag;
                                xin.real=xin.real+t.real;
                                xin.imag=xin.imag+t.imag;
                        }
                }
        }   
}
//fft.h
#ifndef __FFT_H__
#define __FFT_H__         
#include <stm32f10x_lib.h>
//FFT 频谱分析
//可以执行64/128/256/512/1024等点数的FFT计算
//正点原子@SUNTEK
//2010/3/23
   
//傅里叶变换 输入和输出缓存区
typedef struct
{
        float real;
        float imag;
}compx;
                                          
#define FFT_512 //1024点的FFT

#ifdef FFT_64
#define FFT_N 64
#endif
#ifdef FFT_128
#define FFT_N 128
#endif
#ifdef FFT_256
#define FFT_N 256
#endif
#ifdef FFT_512
#define FFT_N 512
#endif
#ifdef FFT_1024
#define FFT_N 1024
#endif         
extern compx fftres[FFT_N];    //FFT数据段
void FFT(compx *xin,u16 N);//N点FFT计算函数
#endif

fft_tab.h
里面就是一个-sin和cos表
#ifndef __FFT_TAB_H__
#define __FFT_TAB_H__          
#include "fft.h"
#include <stm32f10x_lib.h>
//FFT变换的-sin,cos表
//包含64/128/256/512/1024等的-sin,cos表
//正点原子@SUNTEK
//2010/3/23


//cos,-sin,结果储存域;
//制作规则:
//cos_tab:cos(2*pi*x/N);
//sin_tab:-sin(2*pi*x/N);
//其中pi为常数:3.141592;N:傅里叶变换的点数;x:0~N/2-1;  


//64点的-SIN,COS表
#ifdef FFT_64
const float sin_tab[32]=
{
0,-0.0980,-0.1951,-0.2903,-0.3827,-0.4714
,-0.5556,-0.6344,-0.7071,-0.7730,-0.8315,-0.8819
,-0.9239,-0.9569,-0.9808,-0.9952,-1.0000,-0.9952
,-0.9808,-0.9569,-0.9239,-0.8819,-0.8315,-0.7730
,-0.7071,-0.6344,-0.5556,-0.4714,-0.3827,-0.2903
,-0.1951,-0.0980
};
const float cos_tab[32]=
{
1.0000,0.9952,0.9808,0.9569,0.9239,0.8819
,0.8315,0.7730,0.7071,0.6344,0.5556,0.4714
,0.3827,0.2903,0.1951,0.0980,0.0000,-0.0980
,-0.1951,-0.2903,-0.3827,-0.4714,-0.5556,-0.6344
,-0.7071,-0.7730,-0.8315,-0.8819,-0.9239,-0.9569
,-0.9808,-0.9952
};
#endif
其他点数的,依次类推.

一周热门 更多>