找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 9114|回復(fù): 5
收起左側(cè)

音響工程—FFT頻譜

[復(fù)制鏈接]
ID:75263 發(fā)表于 2015-6-9 04:01 | 顯示全部樓層 |閱讀模式
  大學(xué)的第一次電子設(shè)計(jì)競(jìng)賽初賽的題目就是《音頻頻譜柱狀顯示電路》,當(dāng)時(shí)貪玩,沒(méi)能按時(shí)完成作品,因此連晉級(jí)決賽的名額都沒(méi)有,F(xiàn)在回想起來(lái),真的覺(jué)得自己很不爭(zhēng)氣。



圖1  2011年電子設(shè)計(jì)競(jìng)賽初賽題目

   第二年老師重新布置任務(wù),我接到的還是繼續(xù)完成這個(gè)題目,硬件部分的濾波器倒是做好了,并且龍富做好了后期的顯示條部分,但因期末考試的原因沒(méi)能把硬件結(jié)合起來(lái)。
   前些天翻了一下以前的筆記本,一幕幕記憶彌漫出來(lái) 。剛好有點(diǎn)時(shí)間,整理一下思路,決定用FFT算法去實(shí)現(xiàn)這個(gè)功能。 FFT是離散傅立葉變換的快速算法,可以將一個(gè)信號(hào)變換到頻域。有些信號(hào)在時(shí)域上是很難看出什么特征的,但是如果變換到頻域之后,就很容易看出特征了。想想《高數(shù)》、《復(fù)變函數(shù)》、《信號(hào)系統(tǒng)》、《現(xiàn)代自動(dòng)控制系統(tǒng)》、《離散自動(dòng)控制》都有涉及到,也算是專(zhuān)業(yè)知識(shí)了,今天就用它來(lái)實(shí)現(xiàn)多通道帶通濾波器的數(shù)據(jù)解析。

   本設(shè)計(jì)是基于單片機(jī)C的FFT快速傅里葉變換, 用于音頻信號(hào)分析的一個(gè)典型音頻頻譜顯示儀。整體實(shí)現(xiàn)框圖如下:

圖2  整體框架
   MCU控制部分使用32位ARM單片機(jī),7寸TFT彩屏顯示器 ,F(xiàn)FT算法使用純C代碼實(shí)現(xiàn)。整個(gè)實(shí)現(xiàn)過(guò)程中關(guān)鍵的一部分是數(shù)據(jù)的采樣,為了完整的采樣到32768HZ的音頻信號(hào),采用定時(shí)器觸發(fā)ADC,并使用DMA傳送到指定內(nèi)存區(qū)域,再進(jìn)行FFT運(yùn)算。幾天的FFT學(xué)習(xí)和數(shù)據(jù)分析,終于理解了整個(gè)功能的實(shí)現(xiàn)過(guò)程。
   關(guān)鍵部分的是FFT核心轉(zhuǎn)換程序,整理如下(聲明:代碼摘自網(wǎng)上):
   FFT.h頭文件
//                        快速福利葉變換C函數(shù)
//函數(shù)簡(jiǎn)介:此函數(shù)是通用的快速傅里葉變換C語(yǔ)言函數(shù),移植性強(qiáng),以下部分不依
//         賴(lài)硬件。此函數(shù)采用聯(lián)合體的形式表示一個(gè)復(fù)數(shù),輸入為自然順序的復(fù)
//        數(shù)(輸入實(shí)數(shù)是可令復(fù)數(shù)虛部為0),輸出為經(jīng)過(guò)FFT變換的自然順序的
//        復(fù)數(shù)
//使用說(shuō)明:使用此函數(shù)只需更改宏定義FFT_N的值即可實(shí)現(xiàn)點(diǎn)數(shù)的改變,F(xiàn)FT_N的
//         應(yīng)該為2的N次方,不滿(mǎn)足此條件時(shí)應(yīng)在后面補(bǔ)0
//函數(shù)調(diào)用:FFT(s);
//時(shí)   間:2010-2-20
//版   本:Ver1.0
//參考文獻(xiàn):   
#ifndef __FFT_H
#define __FFT_H

#include "math.h"
#define PI 3.1415926535897932384626433832795028841971//定義圓周率值
#define FFT_N512                                     //定義福利葉變換的點(diǎn)數(shù)

struct compx {floatreal,imag;};                  //定義一個(gè)復(fù)數(shù)結(jié)構(gòu)
extern struct compxs[FFT_N];                    //FFT輸入和輸出:從S[1]開(kāi)始存放,根據(jù)大小自己定義

void FFT(struct compx*xin);                      //FFT核心算法
#endif

   FFT.c文件:
#include "FFT.h"
struct compx s[FFT_N];//FFT輸入和輸出:從S[1]開(kāi)始存放,根據(jù)大小自己定義

struct compx EE(struct compx a,struct compxb)     
{
struct compx c;
c.real=a.real*b.real-a.imag*b.imag;
c.imag=a.real*b.imag+a.imag*b.real;
return(c);
}


void FFT(struct compx *xin)
{
  int f,m,nv2,nm1,i,k,l,j=0;
  struct compx u,w,t;
  
  nv2=FFT_N/2;                 //變址運(yùn)算,即把自然順序變成倒位序,采用雷德算法
  nm1=FFT_N-1;
   for(i=0;i
   {
    if(i
    {
     t=xin[j];         
     xin[j]=xin[ i];
     xin[ i]=t;
    }
   k=nv2;                            //求j的下一個(gè)倒位序
   while(k<=j)                  //如果k<=j,表示j的最高位為1  
    {         
     j=j-k;                          //把最高位變成0
     k=k/2;                        //k/2,比較次高位,依次類(lèi)推,逐個(gè)比較,直到某個(gè)位為0
    }
  j=j+k;                           //把0改為1
  }
                        
  {
   intle,lei,ip;                    //FFT運(yùn)算核,使用蝶形運(yùn)算完成FFT運(yùn)算
   f=FFT_N;
  for(l=1;(f=f/2)!=1;l++)  //計(jì)算l的值,即計(jì)算蝶形級(jí)數(shù)
          ;
for(m=1;m<=l;m++)      // 控制蝶形結(jié)級(jí)數(shù)
  {                                      //m表示第m級(jí)蝶形,l為蝶形級(jí)總數(shù)l=log(2)N
   le=2<<(m-1);               //le蝶形結(jié)距離,即第m級(jí)蝶形的蝶形結(jié)相距l(xiāng)e點(diǎn)
   lei=le/2;                         //同一蝶形結(jié)中參加運(yùn)算的兩點(diǎn)的距離
   u.real=1.0;                      //u為蝶形結(jié)運(yùn)算系數(shù),初始值為1
   u.imag=0.0;
   w.real=cos(PI/lei);          //w為系數(shù)商,即當(dāng)前系數(shù)與前一個(gè)系數(shù)的商
   w.imag=-sin(PI/lei);
   for(j=0;j<=lei-1;j++)      //控制計(jì)算不同種蝶形結(jié),即計(jì)算系數(shù)不同的蝶形結(jié)
    {
     for(i=j;i<=FFT_N-1;i=i+le)  //控制同一蝶形結(jié)運(yùn)算,即計(jì)算系數(shù)相同蝶形結(jié)
      {
       ip=i+lei;                      //i,ip分別表示參加蝶形運(yùn)算的兩個(gè)節(jié)點(diǎn)
       t=EE(xin[ip],u);           //蝶形運(yùn)算,詳見(jiàn)公式
       xin[ip].real=xin[ i].real-t.real;
       xin[ip].imag=xin[ i].imag-t.imag;
       xin[ i].real=xin[ i].real+t.real;
       xin[ i].imag=xin[ i].imag+t.imag;
      }
     u=EE(u,w);                    //改變系數(shù),進(jìn)行下一個(gè)蝶形運(yùn)算
    }
   }
  }
}


   FFT分析后的數(shù)據(jù)雖然有一定的規(guī)律,但是還不能滿(mǎn)足頻譜顯示的需求,需在程序控制上針對(duì)顯示器的尺寸進(jìn)行數(shù)據(jù)放縮,頂值限幅等才能輸出酷炫的FFT頻譜界面。
    汗水終究交換了成功,F(xiàn)FT頻譜顯示,如圖:




圖3 FFT普顯示1


圖4 FFT普顯示2



圖5 FFT普顯示3


圖6 FFT普顯示4

回復(fù)

使用道具 舉報(bào)

ID:90256 發(fā)表于 2015-9-16 20:45 | 顯示全部樓層
你qq多少能否加一下
回復(fù)

使用道具 舉報(bào)

ID:97417 發(fā)表于 2015-11-27 22:46 | 顯示全部樓層
您好,想請(qǐng)問(wèn)一下,虛部為什么設(shè)置為0了呢?望解答,謝謝
回復(fù)

使用道具 舉報(bào)

ID:152412 發(fā)表于 2016-12-5 22:07 | 顯示全部樓層
我也在弄
回復(fù)

使用道具 舉報(bào)

ID:393121 發(fā)表于 2018-9-3 19:36 來(lái)自觸屏版 | 顯示全部樓層
想交流一下,加個(gè)QQ唄
回復(fù)

使用道具 舉報(bào)

ID:393121 發(fā)表于 2018-9-18 20:41 | 顯示全部樓層
感覺(jué)好6
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表