C#实现和验证基于频率采样法的FIR滤波器(参考Matlab fir2函数实现)

从WFIR到WIIR:基于频率弯折的音频滤波器设计实战与MATLAB实现 本文深入探讨了基于频率弯折技术的WFIR和WIIR音频滤波器设计,通过MATLAB实现详细展示了从理论到实战的全过程。文章重点解析了频率规整技术如何模拟人耳非线性听觉特性,并提供了优化计算效率和性能的实用技巧,适用于HRTF建模、语音增强等多种音频处理场景。 阅读详情

具体代码

理论知识看各个课本,都有介绍,这里省略。
参考的是Matlab中fir2函数,参考【Matlab帮助中心】fir2函数
在这里插入图片描述

public static double[] fir2(int nn, double[] freqs, double[] mags)
{
    int npt = 512;
    int lap = 0;
    double[] wind;
    nn++;
    if (nn < 1024)
    {
        npt = 512;
    }
    else
    {
        npt = (int)(2 * Math.Ceiling(Math.Log(nn) / Math.Log(2)));
    }

    wind = hamming(nn);

    lap = (int)Math.Floor(npt / 25.0);

    freqs[0] = 0;
    freqs[mags.Length - 1] = 1;
    npt++;

    double[] H = new double[npt];
    int nint = mags.Length - 1;
    double[] df = diff(freqs);
    double nb = 1.0;
    double ne;
    H[0] = mags[0];
    for (int i = 0; i < nint; i++)
    {
        if (df[i] == 0)
        {
            nb = Math.Ceiling(nb - lap / 2.0);
            ne = nb + lap;
        }
        else
        {
            ne = (int)Math.Floor(freqs[i + 1] * npt);
        }

        for (int j = (int)nb; j <= ne; j++)
        {
            double inc = 0;
            if (nb == ne)
            {
                inc = 0;
            }
            else
            {
                inc = (j - nb) / (ne - nb);
            }

            if (j <= H.Length)
            {
                H[j - 1] = inc * mags[i + 1] + (1.0 - inc) * mags[i];
            }
        }
        nb = ne + 1;
    }

    double dt = 0.5 * (nn - 1);
    Complex[] rad = new Complex[npt];
    for (int i = 0; i < npt; i++)
    {
        rad[i] = -dt * Complex.Sqrt(-1.0) * Math.PI * i / (npt - 1.0);
    }

    Complex[] Hc = new Complex[npt];

    for (int i = 0; i < npt; i++)
    {
        Hc[i] = H[i] * Complex.Exp(rad[i]);
    }

    Complex[] newH = new Complex[(npt - 1) * 2];


    newH[0] = Hc[0];
    newH[npt - 1] = Hc[npt - 1];
    for (int i = 0; i < (npt - 1) * 2; i++)
    {
        if (i < npt)
        {
            newH[i] = Hc[i];
        }
        else
        {
            newH[i] = Complex.Conjugate(Hc[(npt-1)*2-i]);//取共轭复数
        }
    }

    var temp = FFTHelper.iFFT(newH, newH.Length); //做快速傅里叶逆变换

    var ht = temp.Select(x => x.Real).ToArray(); //取实部数据

    double[] result = new double[nn];
    Array.Copy(ht, result, nn);  //取前nn个数据
    
    for (int i = 0; i < nn; i++)
    {
        result[i] *= wind[i];
    }

    return result;
}

其中出现的 快速傅里叶逆变换(IFFT) 方法FFTHelper.iFFT参考快速傅里叶变换(FFT)的C#实现及详细注释;

方法diff为差分函数,具体代码如下:

double[] diff(double[] data)
{
    double[] tmp = new double[data.Length - 1];

    for (int i = 0, length = data.Length; i < length - 1; i++)
    {
        tmp[i] = data[i + 1] - data[i];
    }

    return tmp;
}

方法hamming为汉明窗函数,参考【Matlab帮助中心】汉明窗,具体代码:

double[] hamming(int nn)
{
    double[] result = new double[nn];

    for (Int32 i = 0; i < nn; i++)
    {
        result[i] = 2 * Math.PI * i / (nn - 1);
    }

    return result.Select(o => 0.54 - 0.46 * Math.Cos(o)).ToArray();
}

数据验证

int order = 42;
double[]  freqs = { 0, 1 / 20.0, 2 / 20.0, 3 / 20.0, 4 / 20.0, 5 / 20.0, 6 / 20.0, 7 / 20.0, 8 / 20.0, 9 / 20.0, 10 / 20.0, 11 / 20.0, 12 / 20.0, 13 / 20.0, 14 / 20.0, 15 / 20.0, 16 / 20.0, 17 / 20.0, 18 / 20.0, 19 / 20.0, 1 };
double[] mags = { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

C#结果

0.0006145517341182119
0.000880580535935807
0.0008096195245461328
0.0001259640160925836
-0.0012933844793908147
-0.0030050738259155526
-0.0038286109689454305
-0.002307170038675055
0.0022055253858808514
0.008417746435538696
0.012858839141055355
0.01118769172861607
0.0008358319385345649
-0.016268669759934275
-0.03265882126190443
-0.03721408591907582
-0.019766562072078633
0.023447476881272418
0.08625793019711207
0.15316735202088866
0.20442751665090597
0.2236328125
0.20442751665090603
0.1531673520208887
0.0862579301971121
0.023447476881272435
-0.019766562072078615
-0.03721408591907584
-0.032658821261904454
-0.016268669759934285
0.0008358319385345515
0.011187691728616065
0.012858839141055357
0.008417746435538699
0.0022055253858808523
-0.0023071700386750596
-0.0038286109689454327
-0.0030050738259155517
-0.0012933844793908192
0.00012596401609258273
0.0008096195245461329
0.0008805805359358077
0.0006145517341182123

Matlab结果

0.00061455173411821193123899531585153
0.00088058053593580685753511305691177
0.00080961952454613279536732584062975
0.00012596401609258324146879692850831
-0.0012933844793908163932349975056013
-0.0030050738259155529950861218679847
-0.0038286109689454304871869538828832
-0.0023071700386750560937687559714959
 0.0022055253858808505570965330377931
 0.0084177464355386956429416756009232
  0.012858839141055353541553962770649
  0.011187691728616073333357761043771
0.00083583193853456266234763782918549
 -0.016268669759934274721135949448581
 -0.032658821261904440180767750234736
 -0.037214085919075837183278565589717
 -0.019766562072078629197502408487708
  0.023447476881272404092282357623844
  0.086257930197112073211762606206321
   0.15316735202088868628145235106786
   0.20442751665090599932916859415855
                         0.2236328125
   0.20442751665090599932916859415855
   0.15316735202088871403702796669677
  0.086257930197112100967338221835234
    0.0234474768812724422561988291136
 -0.019766562072078611850267648719637
  -0.03721408591907582330549075777526
 -0.032658821261904440180767750234736
 -0.016268669759934288598923757263037
0.00083583193853455182032591297414115
  0.011187691728616066394463857136543
  0.012858839141055355276277438747456
 0.0084177464355386991123886275545374
  0.002205525385880854460224353985609
-0.0023071700386750543590452799946888
-0.0038286109689454322219104298596903
 -0.003005073825915552561405252873783
-0.0012933844793908155258732595171978
 0.0001259640160925829704182538071322
0.00080961952454613279536732584062975
0.00088058053593580729121598205111354
0.00061455173411821225649964706150286

进行了其他阶数的数据验证,这里不一一列出。

总结

  • 进行了8阶和9阶数据对比,基本一致;
  • 进行了31和42阶数据对比,基本一致;
  • 进行了100阶和201阶数据对比,基本一致;
  • 进行了1000阶和1089阶数据对比,基本一致;

使用C#基本上还原了Matlab中fir2函数的实现,但是实现的每一个步骤不是很明确,需要添加每一步的注释。
加油,奥里给!

成形滤波器FPGA实现:128阶FIR设计在Vivado中的4个关键步骤 本文详细介绍了128阶FIR成形滤波器在Xilinx Vivado中的FPGA实现过程,涵盖MATLAB系数生成与定点量化、Vivado FIR IP核配置优化、测试平台设计与数据验证以及资源优化与时序收敛等4个关键步骤。通过函数设计和硬件优化技术,帮助工程师高效完成数字通信系统中的成形滤波器部署。 阅读详情

相关推荐

手把手教你用Matlab+Vivado2021.1搞定Xilinx FIR滤波器IP核(含仿真数据生成避坑指南)

本文详细介绍了如何使用Matlab与Vivado2021.1协同设计Xilinx FIR滤波器IP核,包括滤波器参数设计、COE文件生成、测试向量生成与格式转换、Vivado IP核配置要点以及联合仿真与结果分析。特别提供了仿真数据生成的避坑指南,帮助开发者高效完成数字信号处理任务。

weixin_30847939的博客 360

MATLAB函数——fir2

fir2:基于频率取样法的 FIR 滤波器设计

Josh_Gao 1万+

FIR滤波器结构选择指南:从直冲、转置到分布式算法的工程实践

数字信号处理中的滤波器是实现信号去噪、频率选择等核心功能的基础组件。其本质是通过特定算法对输入序列进行加权求和,从而提取或抑制特定频率分量。不同的实现结构决定了滤波器在硬件或软件中的计算效率、资源占用和时序性能。从最直观的直冲型结构,到为高速流水线优化的转置型结构,再到利用查找表替代乘法器的分布式算法结构,每种结构都在资源、速度和灵活性之间进行权衡。理解这些结构的原理与适用场景,对于在FPGA开发中优化Vivado FIR IP核配置、规避输出失真等常见问题至关重要。例如,在通信系统等对吞吐率要求极高的场景

weixin_34389926的博客 425

C#中实现FIR带通滤波

最近有一个需求,在C#中实现FIR滤波,网上查了些资料感觉FIR滤波使用的还算比较多,相关的原理也比较简单。参考下面在Python环境中实现FIR的博客,在C#的环境中实现了一遍。 https://blog.youkuaiyun.com/moge19/article/details/94495442(Python实现FIR带通滤波器) 下文中的工程下载链接:https://download.csdn.ne...

zhoudapeng01的专栏 4640

别再只会用高斯模糊了!手把手教你用Matlab玩转FIR与IIR图像滤波(附代码)

本文深入探讨了Matlab中FIR与IIR图像滤波技术的实战应用,帮助读者超越传统的高斯模糊方法。通过详细的代码示例和效果对比,展示了如何针对不同噪声类型选择最优滤波方案,包括均值滤波、加权均值滤波以及自适应混合策略,显著提升图像降噪效果。

weixin_30823001的博客 414

FPGA滤波实战:用Vivado FIR IP核滤除8MHz干扰信号,保留2MHz有用信号

本文详细介绍了如何在Xilinx Vivado中使用FIR IP核设计低通滤波器,有效滤除8MHz干扰信号并保留2MHz有用信号。通过MATLAB辅助设计、Vivado IP核配置及硬件优化技巧,实现在Artix-7 FPGA上的高性能信号提纯方案,适用于工业测量和通信系统。

weixin_30835649的博客 208

基于C#的窗函数法低通FIR滤波器

基于C#的窗函数法低通FIR滤波器 摘要 基于Visual Studio 2015 开发环境,使用C#编程语言,运用窗函数法构造了FIR低通滤波器。并通过MATLAB对其滤波效果进行了试验。 由于凯泽窗的数学模型过于复杂,笔者能力有限,故无法在本文中给出凯泽窗的窗函数代码。 源代码 1、矩形窗函数 namespace Low_Pass_FIR_Fliter { class Boxcar ...

BIGFatming的博客 4981

用MATLAB复现经典2ASK调制解调:从原理到代码,一步步教你画出信号波形与频谱图

本文详细介绍了如何使用MATLAB实现2ASK调制解调的全流程可视化,包括信号生成、调制、信道建模和解调优化。通过代码示例和频谱分析,帮助读者深入理解通信原理,并提供了工程优化技巧,如Costas环载波恢复和自适应判决阈值,以提升系统性能。

weixin_30566111的博客 155

C#调用MATLAB生成的32阶FIR带通滤波器参数实现信号实时滤波

这个资源包实现了MATLAB设计与C#执行分离的FIR带通滤波流程。MATLAB端提供三套滤波器设计脚本(FilteDesign1.m~FilteDesign3.m)和主调度脚本FIRMain.m,可灵活配置截止频率、采样率等参数,自动生成32阶FIR滤波器系数并保存为纯文本文件FIRParameters.txt。C#项目FIRTest.sln基于.NET Framework构建,包含控制台程序,能读取该参数文件及待处理信号数据data.txt,通过标准卷积算法完成实时滤波运算,输出结果到dataOut.t

jwt8token的博客 275

MATLAB白噪声生成与应用:从原理到工程实践全解析

白噪声作为一种在所有频率上功率谱密度相等的随机信号,是信号处理与系统分析中的基础概念。其核心原理在于时域上的不相关性与频域上的平坦功率谱,这使得它在模拟理想随机干扰、测试系统响应等方面具有独特的技术价值。在工程实践中,白噪声广泛应用于通信系统仿真、音频设备测试、金融数据建模及心理声学等多个场景。通过MATLAB平台,工程师可以高效地生成、验证与应用白噪声,例如使用randn函数生成高斯白噪声,并通过功率谱密度估计和自相关函数分析进行验证。本文深入探讨了白噪声的生成机制、统计检验方法以及在系统辨识、蒙特卡洛仿

weixin_34224941的博客 445

基于TMS320C5515 DSP的数字听诊器系统:从心音采集到心率检测的完整实现

数字信号处理(DSP)是现代电子设备实现复杂信号分析与控制的核心技术,其原理在于将模拟信号转换为数字序列,通过算法进行实时滤波、变换与特征提取。这项技术的价值在于能够从强噪声背景中精准提取微弱信号,极大地提升了系统的智能化和可靠性。在医疗电子、工业检测和消费电子等领域,DSP技术是实现高精度、高实时性应用的关键。本文聚焦于一个典型的DSP应用场景——数字听诊器系统。该系统利用TMS320C5515 DSP芯片的强大实时处理能力,构建了从模拟心音信号采集、FIR数字滤波到实时心率检测的完整信号链。其中,FIR

dezhen7015的博客 435

告别手动计算系数!手把手教你用MATLAB+ Vivado FIR IP核设计16阶汉明窗低通滤波器

本文详细介绍了如何使用MATLAB和Vivado FIR IP核设计16阶汉明窗低通滤波器的全流程。从MATLAB算法仿真到Vivado硬件实现,重点讲解了参数映射技巧和工程实践中的关键细节,帮助工程师高效完成数字信号处理任务。

weixin_30516243的博客 521

基于树莓派的FPGA测试系统软件架构与核心功能实现

在嵌入式系统与硬件验证领域,构建高效、自动化的测试平台是确保设计质量的关键。其核心原理在于通过分层软件架构,将底层硬件操作与上层测试逻辑解耦,从而实现测试用例的复用与自动化执行。这一方法的技术价值在于显著提升了验证效率与可靠性,尤其适用于FPGA、ASIC等复杂数字逻辑的验证。典型的应用场景包括寄存器读写验证、复杂IP核(如DDR控制器、图像处理流水线)的功能与性能测试,以及将测试流程集成到持续集成(CI)系统中。本文聚焦于如何利用树莓派作为智能测试节点,设计并实现一个涵盖驱动层、协议层、服务层与业务逻辑层

weixin_34038293的博客 373

从linspace到size:5个MATLAB矩阵‘尺码’相关函数,帮你搞定数据形状管理

本文详细介绍了MATLAB中5个核心矩阵形状管理函数,包括linspace、zeros、eye、size和length,帮助开发者高效创建和验证矩阵尺寸。通过实战案例展示了这些函数在信号处理等场景中的协同应用,提升代码效率和正确性。特别适合需要精确控制数据形状的MATLAB用户。

weixin_30527323的博客 728

【语音处理】基于matlab GUI低通滤波器语音信号加噪与去噪【含Matlab源码 1708期】

低通滤波器语音信号加噪与去噪 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 5615

C#实现FIR滤波器(附完整源码)

C#实现FIR滤波器(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 551

数字信号处理_沙沙在哪里?

花了几个月时间终于认认真真把数字信号处理经典部分补完了,学到很多有用的理论,已经开始对某些实际问题的解决产生作用,昨天晚上听歌的时候突然想起一件事情。。。       evergreen是我高一时发现的一首歌,是wma格式,当时听的时候一直在纳闷,为什么总感觉歌声有点杂乱的声音,就是开始那种沙沙的乐器声音,现在来一探究竟,看把它搞出来干掉。。。     首先得把歌曲转换成wav格式,因为M

sprayfly的博客 1250

FIR、IIR数字滤波器的Matlab完整设计

数字滤波器是一种能将输入信号(数字信号)中某一频率范围内的信号分离出来并放大或衰减的系统。它可以实现模拟信号滤波器的功能,是数字信号处理的重要部分。本文提供了 FIR、IIR 数字滤波器的设计方法和 Matlab 代码。使用这些方法可以根据指定的通带、阻带和采样率等参数设计出合适的数字滤波器,从而实现对数字信号的处理和分析。

持续更新 636
上一篇: Debugger.IsAttached 实用性
下一篇: 【FIR窗函数滤波器】C语言实现并与Matlab window+fir1对比
zzzLeaon
博客等级 码龄10年 159粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值