语音信号处理
写作原因
知道了语音信号需要采样率和采样位数,知道了MFCC提取的整个流程,但是中间的幅值变化的细枝末节还是需要细究的,比如:
- matlab/python读取wav文件默认是浮点数,但是保存是整数?
- 调整音频幅度后,MFCC如何变化?
因为是备忘录属性,所以行文口语化,即废话多,重点模糊。
wav文件读取
wav格式
- 标头;
- 第一个区块:声道数量、采样率等信息;
- 第二个区块:数据,以小端序存储。
内容以区块(chunk)为最小单位,每一区块长度为4字节 ,从这可以看出,数据是 整数 还是 浮点数 ,取决于读取的方式。
读取wav文件(matlab/python)
养成读matlab
源代码的习惯:
open function_name
matlab audioread()
audioread(filename, range, datatype)
前两项不做解释。仅关注数据读出类型时,使用 AUDIOREAD(FILENAME, DATATYPE)
,当DATATYPE='double'
时,读出的数据为范围为0.0~1.0
的浮点数;当DATATYPE='native'
时,读出的数据是 采样位数 范围内的整数。
当不加DATATYPE
参数时,读出的数据是浮点数。
% [Y, FS]=AUDIOREAD(FILENAME, DATATYPE) specifies the data type format of
% Y used to represent samples read from the file.
% If DATATYPE='double', Y contains double-precision normalized samples.
% If DATATYPE='native', Y contains samples in the native data type
% found in the file. Interpretation of DATATYPE is case-insensitive and
% partial matching is supported.
% If omitted, DATATYPE='double'.
python
python读wav文件的方式很多,librosa默认是读成浮点数的,待查证。
写入wav文件(matlab/python)
matlab audiowrite()
audiowrite(filename,y,Fs,varargin)
语音数据保存时,不需指定数据类型,数据类型信息包含在数据中,根据该函数的注释内容如下:
% Data Type of Y Valid Range for Y
% -----------------------------------
% uint8 0 <= Y <= 255
% int16 -32768 <= Y <= +32767
% int32 -2^32 <= Y <= 2^32-1
% single -1.0 <= Y <= +1.0
% double -1.0 <= Y <= +1.0
所以如果想用整数保存数据时,一定要先将数据转为目标格式。比如class(ones(1, 16000))
查看数据类型,ones
默认生成double
数据,给它乘上大于1的整型数据,得出的结果依然是double
类型,直接保存wav文件时,大于1.0
的部分被截断,得不到想要的结果。
python
待补充。
audition查看语音幅值
调出 振幅统计 窗口
导航栏 -> 窗口 -> 振幅统计
audition的振幅统计计算如最下面的小字所示,参考的国际电联推荐标准《ITU-R BS.1770-3》。
MFCC
教材上已经有许多MFCC特征提取的步骤了,回过神来,尽是《信号与系统》的基础知识。所以难怪都默认大家能够推导出来吗,真是一段艰难的路程。
还有,不觉得最后这个C
系数很难理解吗?每次教材里给出一堆三角形的Mel banks后,直接DCT然后就得出个系数,通常是一串向量/一个矩阵,真的很难理解。
看matlab一步一步计算,发现一个Mel bank对一帧频谱只得出一个结果,为什么是这样?然后刚才突然想到了:一帧频谱中,对每个刻度的频率只有一个系数来表示,那么一个Mel bank对应的就是一个刻度的频率,所以这个bank的系数就代表了能量,n 个Mel bank得出n个能量系数。所以多帧Mel bank的系数,就叫做Mel 频谱。
至于DCT系数,它对应的应该是傅里叶变换中的那个 e − j ω n e^{-j \omega n } e−jωn(写的是连续傅里叶变换的符号,不过都差不多啦),也就是它的n越多,恢复的信号和原信号的差别越小。
把一帧数目可能是512、1024、2048的频谱变成最多13个的mel频谱,再变回n个DCT系数的信号,语音真是大大压缩了啊。
话说偶尔也能想通这些事情,但是很快就会忘记,重复这样的循环,这次记下来应该就不会忘了吧。另外,突然卷积神经网络!每个卷积层,可以自行设定卷积核的数目,一个卷积核是3维的,宽、高和输入特征层的通道数。普通卷积,首先每个卷积核的通道和对应的特征通道进行计算,然后所有通道相加的结果,作为这个通道的输出。而深度可分离卷积中的depthwise层,只有 一个 卷积核,且每个通道与特征通道计算,但是最后 没有相加 。
与语音幅值的变化关系
参考赵力《语音信号处理实验教程》C3_4_y_4.m
相关程序。
语音信号幅值比较
原语音简单乘以0.5
,用以比较。