用于语音识别的预加重滤波器

信息处理 过滤器设计 有限脉冲响应 过滤
2022-02-05 03:42:40

我正在尝试设计一个:

H(z)=10.95z

FIR 滤波器,用于语音信号。我正在使用arm_fir_example_f32.c如下所示的代码。我需要更改滤波器系数,firCoeffs32. 我对滤波器设计知之甚少,所以我什至不知道代码是否可以理解,但我会尽可能回答。

编辑:更详细地说明我为什么需要这个过滤器。我正在制作一个语音识别器,在这项工作的第 18 页,有一小段关于使用预加重滤波器对语音信号进行频谱平坦化。我认为细节在更高的频率中,所以这就是使用滤波器的原因。

代码:

/* ----------------------------------------------------------------------
 * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
 *
* $Date:         17. January 2013
* $Revision:     V1.4.0
*
* Project:       CMSIS DSP Library
 * Title:        arm_fir_example_f32.c
 *
 * Description:  Example code demonstrating how an FIR filter can be used
 *               as a low pass filter.
 *
 * Target Processor: Cortex-M4/Cortex-M3
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*   - Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   - Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in
*     the documentation and/or other materials provided with the
*     distribution.
*   - Neither the name of ARM LIMITED nor the names of its contributors
*     may be used to endorse or promote products derived from this
*     software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
 * -------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
** Include Files
** ------------------------------------------------------------------- */
#include "arm_math.h"
#include "math_helper.h"
/* ----------------------------------------------------------------------
** Macro Defines
** ------------------------------------------------------------------- */
#define TEST_LENGTH_SAMPLES  320
#define SNR_THRESHOLD_F32    140.0f
#define BLOCK_SIZE            32
#define NUM_TAPS              29
/* -------------------------------------------------------------------
 * The input signal and reference output (computed with MATLAB)
 * are defined externally in arm_fir_lpf_data.c.
 * ------------------------------------------------------------------- */
extern float32_t testInput_f32_1kHz_15kHz[TEST_LENGTH_SAMPLES];
extern float32_t refOutput[TEST_LENGTH_SAMPLES];
/* -------------------------------------------------------------------
 * Declare Test output buffer
 * ------------------------------------------------------------------- */
static float32_t testOutput[TEST_LENGTH_SAMPLES];
/* -------------------------------------------------------------------
 * Declare State buffer of size (numTaps + blockSize - 1)
 * ------------------------------------------------------------------- */
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];
/* ----------------------------------------------------------------------
** FIR Coefficients buffer generated using fir1() MATLAB function.
** fir1(28, 6/24)
** ------------------------------------------------------------------- */
const float32_t firCoeffs32[NUM_TAPS] = {
  -0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f, +0.0085302217f, -0.0000000000f, -0.0173976984f,
  -0.0341458607f, -0.0333591565f, +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f, +0.2229246956f,
  +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f, -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f,
  +0.0080754303f, +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f
};
/* ------------------------------------------------------------------
 * Global variables for FIR LPF Example
 * ------------------------------------------------------------------- */
uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;
float32_t  snr;
/* ----------------------------------------------------------------------
 * FIR LPF Example
 * ------------------------------------------------------------------- */
int32_t main(void)
{
  uint32_t i;
  arm_fir_instance_f32 S;
  arm_status status;
  float32_t  *inputF32, *outputF32;
  /* Initialize input and output buffer pointers */
  inputF32 = &testInput_f32_1kHz_15kHz[0];
  outputF32 = &testOutput[0];
  /* Call FIR init function to initialize the instance structure. */
  arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], blockSize);
  /* ----------------------------------------------------------------------
  ** Call the FIR process function for every blockSize samples
  ** ------------------------------------------------------------------- */
  for(i=0; i < numBlocks; i++)
  {
    arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize);
  }
  /* ----------------------------------------------------------------------
  ** Compare the generated output against the reference output computed
  ** in MATLAB.
  ** ------------------------------------------------------------------- */
  snr = arm_snr_f32(&refOutput[0], &testOutput[0], TEST_LENGTH_SAMPLES);
  if (snr < SNR_THRESHOLD_F32)
  {
    status = ARM_MATH_TEST_FAILURE;
  }
  else
  {
    status = ARM_MATH_SUCCESS;
  }
  /* ----------------------------------------------------------------------
  ** Loop here if the signal does not match the reference output.
  ** ------------------------------------------------------------------- */
  if ( status != ARM_MATH_SUCCESS)
  {
    while (1);
  }
  while (1);                             /* main function does not return */
}
1个回答

对于您的滤波器,抽头数为 2,系数仅为 [-0.95, 1]。

虽然这是一个非常简单的案例,但如果您对 FIR 滤波不太熟悉,它会很有启发性。要从您的传递函数到滤波器实现,将传递函数放在 z 的逆幂方面更容易,因为是单位延迟的 z 变换(一个样本的延迟,无论您正在运行过滤器的采样率 - 有关详细信息,请参阅变换和单位延迟如何/为什么相关? )。z1Z

所以在你的情况下:

H(z)=10.95z
实际上应该如下所示以便成为因果关系(原点的平凡极点被忽略了):

H(z)=10.95zz

这相当于:

H(z)=z10.95

注意只是延迟一个样本的相同信号,实现如下:z1

2 轻按 FIR

其中显示了 2 抽头 FIR 的通用 FIR 结构,在这种情况下可以更简单地显示为:

具有单位增益系数的 2 抽头 FIR

这种滤波器的频率响应很容易确定(例如在 Octave/Matlab 中使用 freqz([-0.95 1]) ,结果如下所示(归一化频率 1 被缩放到滤波器采样频率的一半;所以如果例如,您的采样率为 20 KHz,下图中的频率轴从 DC 变为 10 KHz)。

滤波器传递函数图

另请注意,对于给定的抽头系数的顺序,实现将是“最大相位”。反转抽头会导致相同的幅度响应,但会是“最小相位”,因为主要抽头首先出现。这是 [1 -.95] 而不是 [-.95 1] 的结果频率响应。请注意幅度是如何相同的,但总体相移与频率的关系是如何最小化的:

最小相位传递函数

将最小相位滤波器与最大相位滤波器级联会导致幅度响应恰好是线性相位响应的两倍。[1 -.95] 与 [-.95 1] 的级联是 [-.95 1.9025 -.95] (通过对两者进行卷积得到),这个 3 抽头滤波器的响应是:

线性相位滤波器