音频特征提取及差异

MFCC特征提取步骤:
预加重->STFT->mel滤波->DCT变换->倒谱提升
不同工具提取的特征会有差别,这里选用python中的librosa库分析
预加重:
FIR一阶高通滤波器,提升高频分量,传递函数为

H ( z ) = 1 − a ∗ z − 1 H(z) = 1-a*z{^{-1}} H(z)=1az1

系数a一般取接近1的数如0.97,对应的时域差分方程为

y ( n ) = x ( n ) − a ∗ x ( n − 1 ) y(n) = x(n) - a*x(n-1) y(n)=x(n)ax(n1)

matlab画出滤波器的响应曲线如下

freqz([1,-0.97],1)

这里写图片描述

STFT:
语音信号具有短时平稳性,因此分析时一般通过分帧加窗做短时傅里叶变换

mel滤波:
mel定义了一组从线性频率到mel频率的映射,对应关系为:

m = 2595 l o g 10 ( 1 + f 700 ) = 1127 l o g e ( 1 + f 700 ) m = 2595log_{10}(1+\frac{f}{700})=1127log_{e}(1+\frac{f}{700}) m=2595log10(1+700f)=1127loge(1+700f)

如在librosa库中写法为

2595.0 * np.log10(1.0 + frequencies / 700.0)

mel滤波器是一组分布在mel刻度上的三角窗滤波器,matlab的voicebox中有可以直接得到mel滤波器的函数,写法如下:

fs = 8000;
bank=melbankm(20,512,fs,300/fs,3700/fs,'w');
bank=full(bank);
bank=bank/max(bank(:));
figure,plot(bank(10,:))
figure,plot(bank')

以上程序得到一个 20 ∗ 257 20*257 20257的滤波器组,每一行代表一个频域的三角滤波器,作图plot(bank(10,:))如下

这里写图片描述

画出所有三角滤波器figure,plot(bank’)如下

这里写图片描述

DCT变换:
一般使用的是type-Ⅲ型DCT,DCT变换公式如下

F ( k ) = C ( k ) ∗ ∑ n = 0 N − 1 x k ∗ c o s ( ( 2 n + 1 ) ∗ k π 2 N ) F(k) = C(k)*\sum_{n=0}^{N-1}x_k*cos(\frac{(2n+1)*k\pi}{2N}) F(k)=C(k)n=0N1xkcos(2N(2n+1)kπ)

矩阵形式为

F = G ∗ f F=G*f F=Gf

其中G就是我们需要计算的DCT系数。
这里也说一下各个数据的大小,如我们希望最终每帧数据(帧长400、fft长度512)希望得到13个mfcc系数,而mel滤波器组个数为20,
则各个数据大小如下:
x : 400 ∗ 268 x:400*268 x:400268
x f f t : 512 ∗ 268 xfft:512*268 xfft:512268
m e l c o e f f : 20 ∗ 257 melcoeff:20*257 melcoeff:20257
D C T : 13 ∗ 20 DCT:13*20 DCT:1320
最终得到的就是268帧每帧13个总共13*268个mfcc系数了

需要注意的是,在DCT系数计算中,有的地方直接取 C ( u ) = 2 N C(u)=\sqrt{\frac{2}{N}} C(u)=N2 ,而有的地方在 u > 0 u>0 u>0时不变,在 u = 0 u=0 u=0时取 C ( u ) = 1 N C(u)=\sqrt{\frac{1}{N}} C(u)=N1 ,即如下

![这里写图片描述](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcxMjI4MTExNTUwMDAy?x-oss-process=image/format,png)

关于这里的区别可以查看维基百科关于DCT的介绍:DCT
跟踪librosa的代码可以啊看到librosa是使用第二种方式

    basis = np.empty((n_filters, n_input))
    basis[0, :] = 1.0 / np.sqrt(n_input)

    samples = np.arange(1, 2*n_input, 2) * np.pi / (2.0 * n_input)

    for i in range(1, n_filters):
        basis[i, :] = np.cos(i*samples) * np.sqrt(2.0/n_input)

librosa中提取mfcc很简单,读取音频文件后一行代码就可以完成,以下是mfcc函数内部

# -- Mel spectrogram and MFCCs -- #
def mfcc(y=None, sr=22050, S=None, n_mfcc=20, **kwargs):
    """Mel-frequency cepstral coefficients

    Parameters
    ----------
    y     : np.ndarray [shape=(n,)] or None
        audio time series

    sr    : number > 0 [scalar]
        sampling rate of `y`

    S     : np.ndarray [shape=(d, t)] or None
        log-power Mel spectrogram

    n_mfcc: int > 0 [scalar]
        number of MFCCs to return

    kwargs : additional keyword arguments
        Arguments to `melspectrogram`, if operating
        on time series input

    Returns
    -------
    M     : np.ndarray [shape=(n_mfcc, t)]
        MFCC sequence

    See Also
    --------
    melspectrogram

    Examples
    --------
    Generate mfccs from a time series

    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> librosa.feature.mfcc(y=y, sr=sr)
    array([[ -5.229e+02,  -4.944e+02, ...,  -5.229e+02,  -5.229e+02],
           [  7.105e-15,   3.787e+01, ...,  -7.105e-15,  -7.105e-15],
           ...,
           [  1.066e-14,  -7.500e+00, ...,   1.421e-14,   1.421e-14],
           [  3.109e-14,  -5.058e+00, ...,   2.931e-14,   2.931e-14]])

    Use a pre-computed log-power Mel spectrogram

    >>> S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128,
    ...                                    fmax=8000)
    >>> librosa.feature.mfcc(S=librosa.power_to_db(S))
    array([[ -5.207e+02,  -4.898e+02, ...,  -5.207e+02,  -5.207e+02],
           [ -2.576e-14,   4.054e+01, ...,  -3.997e-14,  -3.997e-14],
           ...,
           [  7.105e-15,  -3.534e+00, ...,   0.000e+00,   0.000e+00],
           [  3.020e-14,  -2.613e+00, ...,   3.553e-14,   3.553e-14]])

    Get more components

    >>> mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)

    Visualize the MFCC series

    >>> import matplotlib.pyplot as plt
    >>> plt.figure(figsize=(10, 4))
    >>> librosa.display.specshow(mfccs, x_axis='time')
    >>> plt.colorbar()
    >>> plt.title('MFCC')
    >>> plt.tight_layout()


    """

    if S is None:
        S = power_to_db(melspectrogram(y=y, sr=sr, **kwargs))

    return np.dot(filters.dct(n_mfcc, S.shape[0]), S)

从代码上看,librosa提取mfcc默认没有预加重和倒谱提升的步骤。
这里附上一个librosa提取mfcc的完整程序。
另外不同的mfcc特征提取工具都或多或少有些不同,如果用一个语言版本提取特征训练模型后移植时用的是另一个语言版本的工具,就一定要先对比清楚两个工具特征的差别,例如librosa默认没有预加重、HTK是直接在原始整型数据基础上做的、matlab版本大多在数据末尾补零的等等,关于mfcc的对比,可以参看这里,还可以看下这篇论文 Comparative_evaluation_of_various_MFCC_implementat
不同MFCCs可能存在的差别:

  • Mel映射关系(如HTK方式与Slaney)
  • Mel滤波器的归一化
  • DCT系数计算方式
  • Mel带数量与宽度
  • Mel频率范围
  • 倒谱提升方式-rasta、htk、或者无
  • 短时傅里叶变换各个参数
  • 抖动或DC消除
  • 预加重
  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值