音频算法入门-傅里叶变换

    上一篇文章中讲了一个时域处理的算法wsola,接下来会学习频域处理算法,在这之前必须得对频域有所了解,这就不得不提傅里叶变换了,本文的目的是让大家学会用傅里叶变换公式和傅里叶逆变换公式进行计算。数学公式是人们对世界中的现象的描述,我们学习数学公式也不该只停留在使用公式来解决问题的层次,得明白公式到底在描述什么现象,从这些天才数学家的角度来看世界。懂的地方可跳过。项目地址在文章末尾给出。

   我直接说结论,傅里叶级数公式包含了傅里叶变换和傅里叶逆变换(不严谨的说就是这么回事)。
    先简单说下具体关系,法国数学家傅里叶发现,任何周期函数都可以用正弦函数和余弦函数构成的无穷级数来表示,这种表示方式就是傅里叶级数。假如有个波形比较复杂的周期函数,那么找出能用来构成这个周期函数的正弦函数和余弦函数的频率的方法就叫做傅里叶变换,用这些频率的正弦函数和余弦函数叠加起来表示这个周期函数的方法就叫做傅里叶逆变换。
    再从公式中看下他们的关系,首先介绍傅里叶级数到底是什么,首先级数是指将数列的项依次用加号连接起来的函数。这么说可能大家还不理解,举个例子:e^x=1+x/1!+x^2/2!+...x^n/n!....,等号左边是指数函数,等号右边就是级数。傅里叶级数公式如下:

    我们主要看这个指数形式的傅里叶级数公式,把求和符号去掉,展开一下就是f(t)=Fa*e^jaω0t+Fb*e^jbω0t+Fc*e^jcω0t+Fd*e^jdω0.....。现在看下面的周期函数叠加效果图,图中显示的是3个周期函数分别在坐标轴(横轴时间,纵轴幅度)的图像,写成傅里叶级数形式就是f(t)=fa(t)+fb(t)+0+0....,这就是傅里叶级数公式要描述的现象。其中Fa*e^jaω0t=fa(t),Fb*e^jbω0t=fb(t),Fc*e^jcω0t=0....。

    看下图的傅里叶变换和逆变换公式,你会发现傅里叶逆变换公式和傅里叶级数公式极其相似,而傅里叶级数系数公式Fn又和傅里叶变换公式极其相似。所以对一个周期函数进行傅里叶级数展开的过程可以认为是先做傅里叶变换再做傅里叶逆变换的过程。

    上图就是傅里叶变换公式也叫连续傅里叶变换公式,有个很重要的事情,就是傅里叶变换公式和逆变换公式一定要一起给出,不然就会让人误解,你们在网上会看到各种各样的写法,但这些写法都是对的,常见的如下图所示。

    为了方便后面的讲解我把角频率ω换成2πf,如上图所示,ω是希腊字母读作Omega,大写是Ω,小写是ω,以后这两个字母会经常看到,都是等于2πf。不要和电学中的电阻单位搞混了,要明白字母只不过是一个符号而已,在不同学科领域都是混着用的,只要不和自己公式中其他字母冲突就行,例如上图傅里叶变换公式中的j其实就是虚数单位i,一般时候我们会把虚数单位写成i,但因为傅立叶变换经常用于电学解决一些问题,为了不和电流符号i混淆,所以公式就把i写成j 。
    要想了解傅里叶变换公式,首先要了解欧拉公式e^ix=cosx+isinx在图像中的含义。以实部的值cosx作为横坐标值,虚部sinx的值作为纵坐标值,x的取值从负无穷到正无穷,画出所有的e^ix点后,你会发现这些点会形成一个周期为2π的圆。如下图1所示(如果不理解,建议看3Blue1Brown的视频,视频连接:https://www.bilibili.com/video/BV1pW411J7s8)

    所以欧拉公式e^ix其实就是随着x的增大而在坐标系上逆时针画圆的过程,那么e^-ix就表示顺时针画圆,e^-i2πx就表示画圆的速度提高2π倍,也就是说x从0到1的过程就是顺时针画出一个完整圆的过程(当然x从1到2或者2到3等等,都能画出一个完整的圆),把x换成t后,e^-i2πt表示每秒都会顺时针画出一个圆。e^-i2πft表示每秒都会顺时针画出f个圆。f(t)表示t时刻的振幅,f(t)函数画出来就是时域波形图。f(t)*e^-i2πft表示每经过1秒会顺时针画出f个圆,并在画圆的同时,t时刻的圆半径要乘上t时刻的振幅,其实就是以每秒的音频振幅数据绕f圈的速度进行旋转缠绕(为了方便理解,没有用复杂的音频数据,用的是一个频率为3的正弦波音频做的实验,请看下图2,图的上半部分是时域波形图,图的左下角是f等于0.4的时候,用公式f(t)*e^-i2πft在实部和虚部构成的坐标系画的图,图的右下角是频谱图,频谱图的横坐标是频率,纵坐标是振幅,振幅的值就是左下角图中数据形成的图案的质心(图中的红点)到坐标系原点的距离的2倍)。当改变f的值,你会发现数据大多数时候是和我们想的一样,以坐标系原点为圆心环绕着,也就是振幅一直都是0,但是当f的值,也就每秒的圈数等于该音频数据的频率时,你会发现一个神奇的现象,那就是所有的数据会在实部或虚部坐标轴的一侧形成一个圆(如下图3所示,如此一来就知道这段音频数据包含了一个频率为3振幅为0.5的正弦波)。所以将多个正弦波叠加的音频数据用傅里叶公式,f从负无穷到正无穷遍历一遍,就可以把这个音频数据里包含的正弦波都一一找出来。(如果不理解,建议看3Blue1Brown的视频,视频连接:https://www.bilibili.com/video/BV1pW411J7s8)

    平时我们说的对音频进行傅里叶变换处理,其实说的是短时离散傅里叶变换。短时离散傅里叶变换的公式(也可以直接叫做离散傅里叶变换公式)如下。

    下面将教大家如何理解这个公式。上面说的连续傅里叶变换公式中有两个原因导致我们无法使用,第一点要求是音频数据的时间从负无穷到正无穷,第二点要求是任意时间t都要有幅度值x(t)才能代入公式进行计算。所以为了解决这两个问题,把公式变为短时且离散的傅里叶变换公式,这个公式可以把一段时间(时间假设为Ts秒)的离散音频数据(有N个采样数据)进行傅里叶变换。你可以把离散傅里叶变换公式理解成连续傅里叶变换的变形,最重要的一点是连续傅里叶变换公式的f和离散傅里叶变换公式的k不是一个意思,他们的关系是k=f*Ts。所以离散傅里叶变换公式也可以写成F(f)=1/n*∑f(t)*e^-j2πf*Ts*n/N,其中的Ts*n/N对应的就是连续傅里叶变换公式的t,只不过这个t没办法取任意时间了,t的取值也就随着n的取值成为了离散的时间点,所以前面的系数由1/2π变为1/N。这样这两个公式就对应起来了。下面将进一步详细介绍这个公式。
    上一段说了k=f*Ts,这段我来解释下为什么,其实离散傅里叶变换公式中k表示的是这段Ts秒的音频数据环绕坐标系原点的圈数,所以k并不是连续傅里叶变换公式里的频率f,而频率f指的是1秒钟震荡的次数,在这个公式中频率f也对应着1秒的音频数据环绕的圈数,所以真正的频率f=k/Ts。
    有人可能会好奇,那为什么不把离散傅里叶变换公式的自变量k换成f呢,这样不是更好理解吗?是会更好理解,但是没有必要,用f的话还要做一次无用的换算。因为采样点只有N个的原因,k的取值范围就被限制住了,k的取值范围只能是0~N-1的整数,这也是为什么用k来做自变量而不是用f的原因。
    还有人可能会好奇,傅里叶逆变换到底是怎么把频域的信息还原回时域的,其实公式计算出来的F(k)是一个复数,这个复数包含了这个频率的周期函数的振幅和相位的信息,假设F(k)=a+ib,,F(k)的模|F(k)|=(a^2+b^2)^1/2,频率f=k/Ts时的振幅为|F(k)|*2(因为求出来的值相当于圆心,但实际上振幅是圆离圆心最远点到坐标原点的距离,所以要乘2),频率f=k/Ts时的相位为arctan(b/a)。所以如果你知道一个周期函数包含了哪些频率的周期函数,并且你这到这些周期函数的振幅和相位,你就可以像下图一样把fa(t)和fb(t)叠加在一起还原回f(t)。傅里叶逆变换的做法略有不同,但意思就是这么个意思,理解了离散傅里叶变换公式的计算,逆变换其实也是差不多代入数值计算就是了。(如果不理解怎么用离散傅里叶变换公式计算,建议看视频,视频里有离散傅里叶变换完整的计算过程,视频连接:https://www.zhihu.com/zvideo/1276595628009377792)

快速傅里叶变换推荐看下面两个视频
https://www.bilibili.com/video/BV1za411F76U
https://www.bilibili.com/video/BV1Jh411d7CN
下面是我用java实现的离散傅里叶变换及逆变换和快速傅里叶变换及逆变换,从他们的运行时间就可以看出来快速傅里叶变换快得多。(学完快速傅里叶变换再想想频谱为何Y轴对称?为何N/2对称?)

  • 闊抽绠楁硶鍏ラ棬-鍌呴噷鍙跺彉鎹
    绛旓細鍌呴噷鍙堕嗗彉鎹㈢殑鍋氭硶鐣ユ湁涓嶅悓,浣嗘剰鎬濆氨鏄繖涔堜釜鎰忔,鐞嗚В浜嗙鏁鍌呴噷鍙跺彉鎹鍏紡鐨勮绠,閫嗗彉鎹㈠叾瀹炰篃鏄樊涓嶅浠e叆鏁板艰绠楀氨鏄簡銆(濡傛灉涓嶇悊瑙f庝箞鐢ㄧ鏁e倕閲屽彾鍙樻崲鍏紡璁$畻,寤鸿鐪嬭棰,瑙嗛閲屾湁绂绘暎鍌呴噷鍙跺彉鎹㈠畬鏁寸殑璁$畻杩囩▼,瑙嗛杩炴帴:https://www.zhihu.com/zvideo/1276595628009377792) 蹇熷倕閲屽彾鍙樻崲鎺ㄨ崘鐪嬩笅闈袱...
  • fft鏄粈涔堟剰鎬
    绛旓細fft鏄闊抽澶勭悊鐨勪竴绉鍙樻崲绠楁硶銆傚揩閫鍌呴噷鍙跺彉鎹锛堣嫳璇細Fast Fourier Transform锛孎FT锛夛紝鏄揩閫熻绠楀簭鍒楃殑绂绘暎鍌呴噷鍙跺彉鎹紙DFT锛夋垨鍏堕嗗彉鎹㈢殑鏂规硶銆傚倕閲屽彾鍒嗘瀽灏嗕俊鍙蜂粠鍘熷鍩燂紙閫氬父鏄椂闂存垨绌洪棿锛夎浆鎹㈠埌棰戝煙鐨勮〃绀烘垨鑰呴嗚繃鏉ヨ浆鎹侳FT浼氶氳繃鎶奃FT鐭╅樀鍒嗚В涓虹█鐤忥紙澶у涓洪浂锛夊洜瀛愪箣绉潵蹇熻绠楁绫诲彉鎹傚洜...
  • fft绠楁硶鐨勫熀鏈師鐞
    绛旓細1.灏嗚緭鍏ュ簭鍒楀垎鎴愬伓鏁板拰濂囨暟涓嬫爣涓や釜瀛愬簭鍒椼2.瀵硅繖涓や釜瀛愬簭鍒楀垎鍒繘琛岄掑綊璋冪敤FFT绠楁硶锛屽緱鍒板畠浠殑DFT缁撴灉銆3.鏍规嵁鍌呴噷鍙跺彉鎹鐨勬ц川锛屽彲浠ラ氳繃杩欎袱涓瓙搴忓垪鐨凞FT缁撴灉璁$畻鍑哄師濮嬪簭鍒楃殑DFT缁撴灉銆傞噸澶嶄笂杩版楠わ紝鐩村埌鏈鍚庡緱鍒扮殑搴忓垪闀垮害涓1锛屽嵆寰楀埌浜嗗師濮嬪簭鍒楃殑DFT缁撴灉銆侳FT绠楁硶鐨勬蹇碉細FFT锛堝揩閫熷倕閲屽彾鍙樻崲...
  • 鍌呴噷鍙跺彉鎹鏈変粈涔堢敤?
    绛旓細鍜鍌呴噷鍙跺彉鎹㈢畻娉瀵瑰簲鐨勬槸鍙嶅倕閲屽彾鍙樻崲绠楁硶銆傝鍙嶅彉鎹粠鏈川涓婅涔熸槸涓绉嶇疮鍔犲鐞嗭紝杩欐牱灏卞彲浠ュ皢鍗曠嫭鏀瑰彉鐨勬寮︽尝淇″彿杞崲鎴愪竴涓俊鍙枫傚洜姝わ紝鍙互璇达紝鍌呴噷鍙跺彉鎹㈠皢鍘熸潵闅句互澶勭悊鐨勬椂鍩熶俊鍙疯浆鎹㈡垚浜嗘槗浜庡垎鏋愮殑棰戝煙淇″彿锛堜俊鍙风殑棰戣氨锛夛紝鍙互鍒╃敤涓浜涘伐鍏峰杩欎簺棰戝煙淇″彿杩涜澶勭悊銆佸姞宸ャ傛渶鍚庤繕鍙互鍒╃敤鍌呴噷鍙跺弽...
  • 鎬庝箞鍒╃敤FFT绠楁硶瀵闊抽鍣0杩涜澶勭悊
    绛旓細fft鏄揩閫鍌呴噷鍙跺彉鎹锛屽畠鏄璋卞垎鏋愮殑涓绉嶉噸瑕佸伐鍏凤紝渚嬪锛屽湪澶勭悊杩囩▼涓娇鐢ㄤ簡蹇鍌呯珛鍙 鍙樻崲fft锛屽洜姝ょ敤骞冲潎鍛ㄦ湡鍥炬硶璁$畻鍔熺巼璋卞瘑搴﹀嚱鏁颁及璁℃槸闈炲父杩呴熺殑
  • 鍌呴噷鍙瀹氬緥鏈夊摢浜涘簲鐢ㄩ鍩?
    绛旓細鍏朵腑锛鍌呴噷鍙跺彉鎹鍙互鐢ㄤ簬鍘嬬缉闊抽鎴栧叾浠栦俊鍙枫傞氳繃灏嗕俊鍙峰垎瑙d负涓缁勬寮︽垨浣欏鸡鍑芥暟鐨勫拰锛屽彲浠ユ壘鍒颁竴涓冻澶熷皬鐨勫瓙闆嗘潵浠h〃鍘熷淇″彿銆傝繖浣垮緱淇″彿鐨勫瓨鍌ㄧ┖闂存洿灏忥紝骞朵笖鍙互鏇村揩鍦颁紶杈撱傜幇浠i煶棰戝帇缂绠楁硶濡侻P3灏变娇鐢ㄤ簡鍌呴噷鍙跺彉鎹㈡潵鍒嗚В闊抽淇″彿銆傞櫎姝や箣澶栵紝鍌呴噷鍙跺畾寰嬭繕鍦ㄦ暟鍊艰绠椾腑鎵紨鐫閲嶈瑙掕壊锛屼緥濡傚湪姹傝В...
  • 鍌呴噷鍙跺彉鎹鍦ㄤ俊鍙蜂紶杈撲腑鐨勫簲鐢
    绛旓細鍌呴噷鍙跺彉鎹鍙互閫氳繃灏嗕俊鍙疯浆鎹㈠埌棰戝煙锛屾壘鍒颁俊鍙峰彈鎹熺殑棰戠巼鎴愬垎锛岀劧鍚庝娇鐢ㄤ慨澶绠楁硶杩涜淇″彿鎭㈠鎿嶄綔銆5銆侀氫俊绯荤粺璁捐锛氬湪鐜颁唬閫氫俊绯荤粺涓紝鍌呴噷鍙跺彉鎹㈣骞挎硾搴旂敤浜庢暟瀛椾俊鍙峰鐞嗐佽皟鍒惰В璋冦佸璺鐢ㄣ佷俊閬撳潎琛°佷俊鍙风爜鍨嬬瓑棰嗗煙銆傚畠涓嶄粎澶уぇ鎻愰珮浜嗛氫俊绯荤粺鐨勬晥鐜囷紝骞朵笖杩樻彁楂樹簡瀵逛簬澶嶆潅淇″彿鐨勮В鏋愬拰鎺у埗銆
  • 闊抽绠楁硶鍏ラ棬-鍙橀煶椤圭洰
    绛旓細浣庨氭护娉㈢殑鐩殑灏辨槸鎶婁綆棰戜俊鍙蜂繚鐣欙紝鎶婇珮棰戜俊鍙烽櫎鍘伙紝杩欑浉褰撲簬鎶婁竴娈闊抽鐨勯鍩熶俊鍙风偣涔榮inc鍑芥暟鍌呴噷鍙跺彉鎹鍚庣殑棰戣氨鍑芥暟锛堣鍑芥暟鐨勫舰鐘惰鐪嬩笂鍥剧殑sinc鍑芥暟棰戣氨鍥撅級銆傞鍩熺偣涔樺張鐩稿綋浜庢椂鍩熷嵎绉紝鎵浠ュ張鐩稿綋浜庢妸涓娈甸煶棰戞椂鍩熶俊鍙峰拰sinc鍑芥暟鍋氬嵎绉紝浣嗘槸鐢变簬sinc鍑芥暟鍦ㄦ椂鍩熶笂鏄粠璐熸棤绌峰埌姝f棤绌风殑锛岃繖灏卞鑷...
  • mp3鐨闊抽瑙g爜
    绛旓細PCM鍙堢О涓鸿剦鍐茶皟鍒舵暟鎹紝鏄绠楁満鍙互鎾斁鐨勬渶鍘熷鏁版嵁锛屼篃鏄痬p3鍘嬬缉鐨勬簮锛屼负浜嗚揪鍒版洿澶х殑鏁版嵁鍘嬬缉鐜囷紝MPEG琛ㄩ拡閲囩敤浜嗗瓙甯︾紪鐮佹妧灏哖CM鏁版嵁鍒嗘垚32涓瓙甯︼紝姣忎釜瀛愬甫閮芥槸鐙珛缂栫爜鐨勶紝鐒跺悗灏嗘暟鎹彉鎹㈠埌棰戝煙涓嬪垎鏋愶紝MPEG閲囩敤鐨勬槸鏀硅繘鐨勭鏁d綑寮﹀彉鎹紝涔熷彲浠ヤ娇鐢鍌呴噷鍙跺彉鎹锛屽啀涓嬫潵涓轰簡閲嶅缓绔嬩綋澹拌繘琛屼簡棰戝煙鎸夌壒瀹...
  • 鍦ㄨ绠楁満绉戝棰嗗煙涓,浜ら敊椤圭骇鏁版湁鍝簺甯歌搴旂敤?
    绛旓細浜ら敊绾ф暟鍦ㄨ绠楁満绉戝棰嗗煙涓湁璁稿甯歌鐨勫簲鐢ㄣ備互涓嬫槸鍏朵腑涓浜涗富瑕佺殑搴旂敤锛1.淇″彿澶勭悊锛氫氦閿欑骇鏁板湪鏁板瓧淇″彿澶勭悊涓骞挎硾搴旂敤銆備緥濡傦紝閫氳繃灏嗕俊鍙峰垎鎴愪氦閿欑殑瀛愬簭鍒楋紝鍙互闄嶄綆璁$畻澶嶆潅搴﹀苟鎻愰珮绠楁硶鐨勬晥鐜囥傝繖绉嶆妧鏈父鐢ㄤ簬闊抽鍜岃棰戠紪瑙g爜鍣ㄤ腑锛屼互瀹炵幇楂樻晥鐨勯璋卞垎鏋愬拰婊ゆ尝鎿嶄綔銆2.蹇鍌呴噷鍙跺彉鎹锛團FT锛夛細FFT鏄...
  • 扩展阅读:5种常见音频格式 ... 傅里叶级数完整公式 ... 音频转换器 ... 傅里叶变换公式图片 ... 万能音频转换器 ... 音频文件参数 ... 音频算法工程师自学 ... 傅里叶变换全部公式 ... 音频文件大小计算 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网