写在前面
不是科研狗,基础理论薄弱,写的比较匆忙,有理解有误的地方还请理解和指正。
网上大佬们写的傅里叶公式推导,证明已经很多了(瑟瑟发抖),我这里主要是讲傅里叶的应用,不涉及公式证明,而是直接拿起公式使用。
由于自己获取知识也是看大佬们博文理解学习得来的,所以图片中多少有一些是别人的图,不过我附上了别人的链接。
看完这篇你能收获到:
1 傅里叶变换的原理
2 傅里叶变换在音频的应用
3 离散傅里叶变换处理音频的C语言代码及讲解

背景
最近接触音视频处理比较多,就遇到了采集的音频数据有噪音的情况。可不可以用傅里叶变换去除音频噪音呢?在此之前,我对傅里叶变换的概念只有一句话,“时域转频域的一个玩意儿”。我将音频时域转为频域,再去除噪音的频段,不就达到去噪的效果吗? 嗯,试试就逝世。
嗯,经过几天的折腾,效果(上图为原始音频信号,下图为在频域去掉高频正交基后的音频信号)
结论:
1,有点效果,但噪音只是变小了,没有去除。使用的是DFT,还有待改进。
2,琢磨了一段时间,还有诸多地方没有理解到,傅里叶变换是需要长期研究和推敲的学问。把自己理解到的知识点做下笔记,以后要走图像处理什么的路子,再来细细研究吧。

一 什么是傅里叶变换(分析)?
可以参考这篇
在回答这个问题的时候,我们需要先知道什么是变换?为什么要变换?

(1)什么是变换?
举个大家常用的例子,两个向量,a,b在坐标系中表示,可以变换为一组坐标。

(2)为什么变换?
比如想求c点坐标,在图中是不好处理的问题,但是变换后,c=a+b=(2+1,1+2)=(3,3) ,在数上就很好处理了。总之,一个问题不好处理的时候,换个思路(变换),就能迎刃而解。嗯嗯,有点像线性代数的味道。
傅里叶变换的思路就是时域和频域的相互变换。

二 时域和频域
时域和频域一一对应,通过频域可以变换为时域

傅里叶变换类型
傅里叶变换有许多类型,通常不加前缀说的是连续傅里叶变换,离散傅里叶变换常用在计算机处理上,在此之上进行算法改进,降低时间复杂度,叫快速傅里叶变换。

对于时域是周期性连续的函数进行变换叫傅里叶级数
对于时域是非周期连续的函数进行变换叫傅里叶变换

三傅里叶级数(Fourier Series)
所以啊,傅里叶就提出了这句话:任何周期函数都由多个不同的正弦波(sin和cos)叠加构成(满足狄里赫利条件情况下)
如图,频域由若干个正弦波构成,时域的矩形波可以由多个正弦波叠加构成(当正弦波个数趋向无穷大,逼近为矩形波,有点极限的赶脚)

周期函数其实说的就是时域信号,多个不同的正弦波说的是频域的信号。

当然,如上图所示,一个正弦波的确定,需要知道他的相位,振幅和角频率,所以时域转频域得到的是一系列的初相,振幅和角频率。
傅里叶说的这句话写成公式就是

又或者可以这样写

这个公式该这么理解呢?这就需要知道正弦波的正交性。

(1)正弦波的正交性
正弦波自己给自己内积为1,自己和别人内积为0,也就是sin(nwt),cos(nwt)都是标准正交基,再加上常量1, 任何的周期函数都可以用着三个表示 。所以呢,只需要将时域的f(t)分别和各种标准正交基做内积,等于0代表没有该正弦波,否则存在该分量。

什么是标准正交基
线性代数:在空间中找到一组向量,他们的内积为0,自身的模为1时,称这组向量为标准正交基,空间中的任意向量都可以由这些标准正交基构成。

什么是内积?
嗯,你需要学习到晚上2点[手动滑稽]

三傅里叶变换公式

(1) 欧拉公式
但上图的f(t)没有和各种正弦波做内积啊,而是和e^-iwt 做内积。其实这是欧拉公式将正弦波与指数之间进行了变换,本质上上图公式就是和各种正弦波做内积。现在就说说欧拉公式。

数系
回顾下初中知识
自然数:1,2,3,4。。。
整数:-1,1,-2,2.。。。
有理数:-1,2,2/3,4/5.。。
无理数:根号2等
这些一起就构成了实数,如图 实数轴。
但遇到x^2=-1这样的解,用实数就无法解决了,引入虚数。虚数+实数=复数,如图为复平面,任意点可以用a+bi 来表示

在复平面上画圆,由三角公式,可以求得a点为cosx+i *sinx。
复平面上乘法的意义:
乘-1,逆时针旋转180度。乘-i ,逆时针旋转90度,复数乘法如图

现在就可以 拿出欧拉公式了

公式推导就是使用的泰勒公式,e,sin,cos都是十大必背泰勒展开式,两边展开是相等的。
到这里就打住吧,总之我们到这里能知道傅里叶变换公式e^iwt其实就是与各个sin,cos做内积。具体欧拉公式讲解可以看这篇
欧拉公式讲解
欧拉恒等式
也就是角度到达180度时候,又回到实数轴

离散傅里叶变换(DFT)
离散傅里叶变换可以参考这篇
离散傅里叶变换讲解
离散和连续的区别在于,连续是积分而离散是求和

原理,如下图,a,b图是待检测信号,c,d是3个周期的正弦信号,很显然a图含有正弦波,e=ac,将e图的各点相加,很显然值是正的,这就说明a图含频率为3的正弦波,f=bd,显然将f图中各点相加结果约等于0了,说明b图不含有周期为3的正弦波

在计算机中用这个公式更好处理一点

n和N是在一个正弦周期内采样N个点,采样间隔为2pi\N,n用来步进,一次步进2pi\N,最后进行累加求和,就得出了X(k)

最后 离散傅里叶变换完整代码
1,从文件读取8000个音频数据,由于现实中的音频没有虚部,所以只设置实部。
2,离散傅里叶变换关键处
temp的re就是对应上图公式的cos,同理im就是对应上图的sin,每个X[k]进行累加求和

for (int k = 0; k < N; k++)
    {
        X[k].re = 0;
        X[k].im = 0;
        for (int n = 0; n < N; n++)
        {
            temp.re = (float)cos(2 * pi*k*n / N);
            temp.im = -(float)sin(2 * pi*k*n / N);
            X[k] = complexadd(X[k], complexMult(x[n], temp));
        }    
    }

3,离散傅里叶逆变换就是X(k)乘上e^(j2tkn/N),也就是实部虚部都为正

temp.re = (float)cos(2 * pi*k*n / N);
            temp.im = (float)sin(2 * pi*k*n / N);
            x[k] = complexadd(x[k], complexMult(X[n], temp));
1
2
3
4,下图公式求幅度

在代码中表示

printf("%d ", int(2.0/N*sqrt(X[k].re*X[k].re + X[k].im*X[k].im)));
//打印的为幅度
1
2
完整代码

#include <stdio.h>
#include <math.h>

#define pi 3.1415926
struct complex
{
    float re;
    float im;
};

complex complexadd(complex a, complex b) { //复数加
    complex rt;
    rt.re = a.re + b.re;
    rt.im = a.im + b.im;
    return rt;
}

complex complexMult(complex a, complex b) { //复数乘
    complex rt;
    rt.re = a.re*b.re - a.im*b.im;
    rt.im = a.im*b.re + a.re*b.im;
    return rt;
}
complex complexSet(complex *a, short *b, int N)//复数设置
{
    for (int i = 0; i < N; i++)
    {
        a[i].re = b[i];
        a[i].im = 0;
    }
}

//离散傅里叶变换
//X[]标识变换后频域,x[]为时域采样信号
void dft(complex X[], complex x[], int N)

    complex temp;
    int k, n;
    for (int k = 0; k < N; k++)
    {
        X[k].re = 0;
        X[k].im = 0;
        for (int n = 0; n < N; n++)
        {
            temp.re = (float)cos(2 * pi*k*n / N);
            temp.im = -(float)sin(2 * pi*k*n / N);
            X[k] = complexadd(X[k], complexMult(x[n], temp));
        }    
        printf("%d ", int(2.0/N*sqrt(X[k].re*X[k].re + X[k].im*X[k].im)));
//打印的为幅度
        if (k >= 6000)//去除高频信号
        {
            X[k].re = 0.0;
            X[k].im = 0.0;
        }
    }
}
//离散傅里叶逆变换
//X[]标识变换后频域,x[]为时域采样信号
void idft(complex X[], complex x[], int N) {
    complex temp;
    //int k, n;
    for (int k = 0; k < N; k++)
    {
        x[k].re = 0;
        x[k].im = 0;
        for (int n = 0; n < N; n++)
        {
            temp.re = (float)cos(2 * pi*k*n / N);
            temp.im = (float)sin(2 * pi*k*n / N);
            x[k] = complexadd(x[k], complexMult(X[n], temp));
        }
        x[k].re /= N;
        x[k].im /= N;
    }
}

#define N 8000//采样率为8000
int main() {
    complex samples[N], X[N], x[N]; //原始数据,变换后的频域数据,逆变换后的时域数据
    FILE *fp;
    FILE *fp2;
    short buf[N];
    int re=0;
    fp=fopen("./ttt.pcm", "rb");
    fp2 = fopen("./trans.pcm", "wb");
    if (!fp ||!fp2) {
        printf("I could not open file.\n");
        return 1;
    }
    else
    {
        while (fread(buf, sizeof(short)*N,1 , fp) > 0)//末尾数据忽略
        {
            complexSet(samples, buf, N);
            dft(X, samples, N);
            idft(X, x, N);
            for (int i = 0; i < N; i++)
            {
                buf[i] = x[i].re;
            }
            fwrite(buf, sizeof(short)*N,1 , fp2);
        }
    }
    fclose(fp);
    fclose(fp2);
    return 0;
}
————————————————
版权声明:本文为CSDN博主「工农村贴膜小哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35651984/article/details/106455170

[音频处理]傅里叶变换去噪相关推荐

  1. matlab傅里叶变换去噪代码,小波的分析在心电信号去噪中应用(内附Matlab去噪源代码).ppt...

    求职应注意的礼仪 求职时最礼貌的修饰是淡妆 面试时最关键的神情是郑重 无论站还是坐,不能摇动和抖动 对话时目光不能游弋不定 要控制小动作 不要为掩饰紧张情绪而散淡 最优雅的礼仪修养是体现自然 以一种修 ...

  2. 音频小波去噪(sym8和db)后语谱图对比标注

    单轨道音频信号 Sym Lev=7 Dblev4 Db lev=3 语谱图: 原音频(多音道) 单轨道 Db lev=4

  3. matlab傅里叶变换去噪代码,[转载]MATLAB小波去噪

    MATLAB中用wnoise函数测试去噪算法 sqrt_snr=3; init=231434; [x,xn]=wnoise(3,11,sqrt_snr,init); % WNOISE generate ...

  4. 音频降噪算法 java_音频处理之去噪算法---基于pcm和g711的音频16000hz、8bit去噪声算法...

    (1)应用背景 (2)主要降噪算法原理 (3)算法流程 (4)算法实现 (5) ------------author:pkf -------------------time:2-6 --------- ...

  5. 基于傅里叶变换的音频重采样算法 (附完整c代码)

    前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲, ...

  6. 基于MATLAB的数字滤波器语音信号去噪

    文章目录 一.滤波器的种类及简介 二.设计流程 三.滤波器设计实现与结果仿真 参考文献 基于MATLAB的FPR滤波器设计源代码 本课程设计通过分析FIR滤波器的基本原理,在MATLAB环境下利用窗函 ...

  7. python计算无穷级数求和常用公式_傅里叶变换(二) 从傅里叶级数到傅里叶变换...

    在上一部分当中,得到了利用三角函数表示周期函数的方法,但是对于非周期函数就...凉了.所以有什么办法吗?没办法(划掉).这时候我们就需要拿出来我们的黑科技--傅里叶变换. 一.傅里叶级数的推广 当然这 ...

  8. 短时傅里叶变换(STFT)实例

    记录学习音频短时傅里叶变换的过程,注意,这里并不会讲述傅里叶变换的原理 想了解原理可以自行搜索或查看文中的参考文章 运行使用Pycharm,环境为python3.10 1.导入软件包,设置快速傅里叶变 ...

  9. 图卷积神经网络的数学原理——谱图理论和傅里叶变换初探

    Math of GCN 一.warmup 1.Graph vs Image ①Graph是相比于Image更加广义的一种拓扑结构. ②Image是Grape在欧式空间的一种特例. 2.符号含义 ①A: ...

  10. librosa 音频处理

    目录 序言 一.libsora安装 pypi conda source 二.librosa常用功能 核心音频处理函数 音频处理 频谱表示 幅度转换 时频转换 特征提取 绘图显示 三.常用功能代码实现 ...

最新文章

  1. SSL协议安全系列:PKI体系中的证书吊销
  2. 2017年中国自动驾驶最全产业研究报告 99页
  3. 5.2.4.最简单的模块源码分析3
  4. OpenGL球体的Phong渲染
  5. JavaScript —从回调到异步/等待
  6. mysql查询数据库第一条记录_SQL获取第一条记录的方法(sqlserver、oracle、mysql数据库)...
  7. SVN遗漏so文件的解决办法
  8. 【期末划重点】电路与电子技术基础
  9. Android NDK 建立cocos2dx项目
  10. 电阻用计算机怎么算,电阻分压计算器_电阻分压计算公式_电阻分压计算软件 - 电子发烧友(www.elecfans.com)...
  11. 秀动app抢票脚本_GitHub标星2.5万的quot;Python抢票教程”!
  12. 如何设置 IntelliJ IDEA 主题和字体
  13. 图片鼠标移入图片改变颜色、显示另外一张图片(2种方式)
  14. DirectShow入门
  15. win 7 64位系统安装java jdk 遇到could not find the required version of the java 2 runtime environment 错误
  16. 企业网站新闻显示页面(HTML+CSS)
  17. 洛谷P1496 火烧赤壁
  18. 消息队列——ActiceMQ
  19. 代码制作数字流星雨_用C语言编写流星雨程序
  20. 用 Node.js 写一个多人游戏服务器引擎

热门文章

  1. Mugeda(木疙瘩)H5案例课—H5酷炫特效制作-岑远科-专题视频课程
  2. 华为荣耀4X的ROOT
  3. java-pdf-itext7、itextpdf 生成pdf 文档 定制票据打印
  4. Chrome插件开发入门
  5. lora网关软件设计_LoRa网关 - 舜为互联
  6. (152)IES光源概述文件
  7. 4. 嵌入式OpenWRT入门基础篇-----设置OpenWRT系统为AP、中继模式
  8. iphone手机投屏到电脑 苹果手机不知道的功能
  9. python实现人民币大小写转换
  10. 高分一号和资源三号卫星数据产品的级别