在音频文件上应用频率采样过滤器

时间:2017-04-16 16:46:41

标签: matlab audio filtering signal-processing

我正在尝试使用来自给定数据文件的频率采样来应用双带阻滤波器。 我使用的方法如下

  1. 给定频率采样文件的反向fft(relief='edge'

  2. 从步骤1给出的实际值的循环移位

  3. 执行第2步

  4. 的结果
  5. 使用卷积在音频文件上应用滤镜。 (频域)

  6. 问题是带阻频率(925Hz和2090Hz)仍然存在。我的代码有什么问题,或者我错过了什么?

    ifft

    Frequency Spectrum

    任何人都可以帮助我吗?

    the data file plotted before ifft

1 个答案:

答案 0 :(得分:0)

前两步

  
      
  1. 给定频率采样文件的反向fft(ifft
  2.   
  3. 从步骤1给出的实际值的循环移位
  4.   

应该正确地为您提供根据您的规范构建的过滤器的时域系数,前提是freqSampling.txt文件正确指定了所需的完整双面光谱(请参阅"验证规范"下面) 。如果频率规范包含陡峭的瞬变,则还可能需要调整/增加ifft点的数量。然而,如步骤4所示,在频域中执行卷积并不对应于典型的滤波操作,而是等效于两个信号的时域乘法。

时域过滤

从第2步的结果中,您可以使用wave直接在时域中过滤conv数据:

new_sound = conv(r, wave);

filter

new_sound = filter(r, 1, wave);

conv会给你完整的length(wave)+length(r)-1卷积,而filter是一个更多的信号处理导向函数,返回卷积的第一个length(wave)个样本(也可以处理conv不直接支持的递归过滤器。

频域过滤

或者在频域中执行过滤

  1. 使用至少length(r)+length(wave)-1
  2. 的大小对步骤2的结果执行FFT
  3. 使用与步骤3中相同的大小执行wave数据的FFT
  4. 使用乘法(频域)在音频文件上应用滤镜。
  5. 计算步骤5
  6. 结果的逆FFT(ifft
  7. 从第6步中获取结果的实际部分(技术上不是必需的,但由于数字舍入误差较小而经常需要)
  8. 可以使用以下方法实现:

    N = length(wave)+length(r)-1;
    wave_fd = fft(wave, N);              % step 3
    filter_fd = fft(r, N);               % step 4
    
    filtered_fd = wave_fd .* filter_fd;  % step 5
    new_sound = real(ifft(filtered_fd)); % step 6 & 7
    

    请注意,您还可以使用the overlap-add method以较小的块执行此频域过滤操作。

    验证规范

    根据您的评论,data文件导入的freqSampling.txt可以通过以下方式重建:

    N = 401;
    data = ones(N,1);
    data(19:23) = [2 1 0 1 2]/3;
    data(51:56) = [2 1 0 1 2]/3;
    data(N-[2:(N+1)/2]+2) = data([2:(N+1)/2]);
    

    为了验证这会过滤所需的频率,我们可以将此规范绘制为频率的函数。为此,我们需要使用的采样率(fs),根据您的图表,它似乎是22050。然后,您应该能够用以下内容绘制这些:

    hold off; plot([0:N-1]*fs/N, data);
    hold on;  plot([925 925;2090 2090]', [0 1.2;0 1.2]', 'k:');
    axis([0 3000 0 1.2]);
    xlabel('Frequency (Hz)');
    ylabel('Amplitude');
    legend('Specs', 'Tones');
    

    哪个应该给出如下情节: buggy specifications

    基于此,似乎规格在音调频率上不提供任何衰减。可以用以下方法构建更好的拟合:

    N = 401;
    data = ones(N,1);
    data(round(925*N/fs)+1+[-2:2]) = [2 1 0 1 2]/3;  % data([16:20])
    data(round(2090*N/fs)+1+[-2:2]) = [2 1 0 1 2]/3; % data([37:41])
    data(N-[2:(N+1)/2]+2) = data([2:(N+1)/2]);
    

    产生一个如下所示的验证图: adjusted specifications

    P.S。:根据你的信号的频域图,似乎第二个音调更接近2600Hz,而不是指示的2090Hz。