关于MFCC的一些笔记(python)

练习笔记 专栏收录该内容
2 篇文章 0 订阅

为什么要用MFCC?即使不应用于人类语音领域
理解Mel频谱图
语音合成中的Mel谱和MFCC谱无区别
一些参数
pre_emphasis = 0.97 #经过预加重处理后的结果为y(n))=x(n)-ax(n-1),这里取a=0.97
NFFT = 512 #窗宽
nfilt = 40 #滤波器数
num_ceps = 12 #L阶梅尔参数默认

大体过程

  1. #–预先处理y(n))=x(n)-ax(n-1)
  2. #–将信号转为帧
  3. #–定义函数对原信号的每一帧进行变换,应该是为了消除关联性
  4. #–加上汉明窗
  5. #–傅立叶变换得到幅度谱,功率谱等于每一点的幅度平方/NFFT
  6. #–将频率转换为Mel
  7. #–DCT变换
  8. #–升倒谱系数
    一个音频最终得到一个(77,13)的mfcc系数阵,77个帧(帧数和你所定的帧大小和信号长度有关),每帧13阶系数(一个对数系数,12个梅尔倒谱系数)

代码主要使用了https://www.cnblogs.com/dylancao/p/9790707.html
但是我自己加了一阶系数,原代码没有保留对数系数,改了下

   #!/usr/bin/python
  # -*- coding: UTF-8 -*-

import numpy
import scipy.io.wavfile
from matplotlib import pyplot as plt
from scipy.fftpack import dct

pre_emphasis = 0.97   #经过预加重处理后的结果为y(n))=x(n)-ax(n-1),这里取a=0.97
NFFT = 512   #窗宽
nfilt = 40   #滤波器数
num_ceps = 12  #L阶梅尔参数
low_freq_mel = 0
sample_rate,signal=scipy.io.wavfile.read('D:/日本/藤村流程/reference/IDMT-ISA-ELECTRIC-ENGINE/train_cut/engine1_good/pure_0.wav')  #采样频率,信号

print(sample_rate,len(signal))
 #读取前3.5s 的数据
#signal=signal[0:int(3.5*sample_rate)]
print(signal.shape)



 #--预先处理将信号转为帧

emphasized_signal = numpy.append(signal[0], signal[1:] - pre_emphasis * signal[:-1])   #第一个信号signal[0]不进行处理
print('em_signalshape', emphasized_signal.shape)
frame_size=0.025
frame_stride=0.01
frame_length,frame_step=frame_size*sample_rate,frame_stride*sample_rate ##帧长#帧移
signal_length=len(emphasized_signal)  #处理后的信号
frame_length=int(round(frame_length)) #四舍五入后取整
frame_step=int(round(frame_step))
num_frames=int(numpy.ceil(float(numpy.abs(signal_length-frame_length))/frame_step))  #一共多少个帧,分帧完成
print('帧数',num_frames)

#--定义函数对原信号的每一帧进行变换,应该是为了消除关联性
pad_signal_length=num_frames*frame_step+frame_length
z=numpy.zeros((pad_signal_length-signal_length))
pad_signal=numpy.append(emphasized_signal,z)

indices = numpy.tile(numpy.arange(0, frame_length), (num_frames, 1)) + numpy.tile(numpy.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T

frames = pad_signal[numpy.mat(indices).astype(numpy.int32, copy=False)]
print('framelengtth', frame_length)

#--加上汉明窗
frames *= numpy.hamming(frame_length) #8列
 # frames *= 0.54 - 0.46 * numpy.cos((2 * numpy.pi * n) / (frame_length - 1))  # Explicit Implementation **
print('frameshape', frames.shape)

 #--傅立叶变换和功率谱

mag_frames = numpy.absolute(numpy.fft.rfft(frames, NFFT))  # Magnitude 幅度of the FFT
print(mag_frames.shape)
pow_frames = ((1.0 / NFFT) * ((mag_frames) ** 2))  # Power Spectrum #功率谱等于每一点的幅度平方/NFFT
print('功率谱shape', pow_frames.shape)
energy = numpy.sum(pow_frames, 1)  # 对每一帧的能量谱进行求和
energy = numpy.where(energy == 0, numpy.finfo(float).eps, energy)  # 对能量为0的地方调整为eps,这样便于进行对数处理

 #--将频率转换为Mel

high_freq_mel = (2595 * numpy.log10(1 + (sample_rate / 2) / 700))
mel_points = numpy.linspace(low_freq_mel, high_freq_mel, nfilt + 2)  # Equally spaced平均分配nfilt个三角滤波器 in Mel scale
hz_points = (700 * (10**(mel_points / 2595) - 1))  # Convert Mel to Hz

bin = numpy.floor((NFFT + 1) * hz_points / sample_rate)  #滤波器组的中心频率

fbank = numpy.zeros((nfilt, int(numpy.floor(NFFT / 2 + 1))))   #滤波器组传递初始化

for m in range(1, nfilt + 1):
     f_m_minus = int(bin[m - 1])   # left下限
     f_m = int(bin[m])             # center中心
     f_m_plus = int(bin[m + 1])    # right上限
     for k in range(f_m_minus, f_m):
        fbank[m - 1, k] = (k - bin[m - 1]) / (bin[m] - bin[m - 1])
     for k in range(f_m, f_m_plus):
         fbank[m - 1, k] = (bin[m + 1] - k) / (bin[m + 1] - bin[m])
filter_banks = numpy.dot(pow_frames, fbank.T)  #滤波器组(能量谱,传递函数)
filter_banks = numpy.where(filter_banks == 0, numpy.finfo(float).eps, filter_banks)  # Numerical Stability
filter_banks = 20 * numpy.log10(filter_banks)  # dB对数
print('fileterbanks.shape',filter_banks.shape)

#--DCT
mfcc = dct(filter_banks, type=2, axis=1, norm='ortho')[:,  : (num_ceps + 1)]  #DCT离散余弦变换,第一个之后用能量的对数来代替
(nframes, ncoeff) = mfcc.shape

#升倒谱系数
n = numpy.arange(ncoeff)
cep_lifter =22 #默认为22
lift = 1 + (cep_lifter / 2) * numpy.sin(numpy.pi * n / cep_lifter) #升倒谱系数
mfcc *= lift  #*
log13 = numpy.log(energy)
mfcc [:,0] = numpy.log(energy)

#filter_banks -= (numpy.mean(filter_banks, axis=0) + 1e-8)
mfcc -= (numpy.mean(mfcc, axis=0) + 1e-8)
print('mfcc',mfcc)
print('mfcc。shape=(帧数,阶数)',mfcc.shape)
plt.plot(filter_banks)

plt.show()

不懂待改动的点
另外MFCC还有一个delta动态特征的过程,暂时没管。
另外还看到有的MFCC算了这些:13个MFCC+13个一阶微分系数+13个加速系数,一共39个系数
不知道这多出来的系数是个啥子意思。。。

更新
发现另外26个系数还是很有用的,于是加上…
一阶13个系数就是对原13个系数进行求微分的操作…
二阶对一阶求。
作用如下:The MFCC feature vector describes only the power spectral envelope of a single frame, but it seems like speech would also have information in the dynamics i.e. what are the trajectories of the MFCC coefficients over time. It turns out that calculating the MFCC trajectories and appending them to the original feature vector increases ASR performance

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页

打赏作者

qq_40140755

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值