- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
语音数据和视频数据不同,本没有帧的概念,但是为了传输与存储,我们采集的音频数据都是一段一段 的。为了程序能够进行批量处理,会根据指定的长度(时间段或者采样数)进行分段,结构化为我们编程 的数据结构,这就是分帧.
由于我们常用的信号处理方法都要求信号是连续的,也就说必须是信号开始到结束,中间不能有断开。然 而我们进行采样或者分帧后数据都断开了,所以要在帧与帧之间保留重叠部分数据,以满足连续的要求, 这部分重叠数据就是帧移.
介绍帧移的时候我们说了,我们处理信号的方法都要求信号是连续条件,但是分帧处理的时候中间断开 了,为了满足条件我们就将分好的帧数据乘一段同长度的数据,这段数据就是窗函数整个周期内的数据, 从最小变化到最大,然后最小.
我们知道,我们处理的语音其实是一种声波,声波是一种物质波。滤波的字面意思理解为过滤一些不同频 率的波。根据傅里叶变换,我们知道任意波可以分解为几种正弦波和余弦波的叠加,从概率论的角度,滤 波即加权。 滤波的作用就是给不同的信号分量不同的权重。最简单的loss pass filter, 就是直接把低 频的信号给0权重,而给高频部分1权重。对于更复杂的滤波,比如维纳滤波, 则要根据信号的统计知识来 设计权重.
当允许信号中较高频率的成分通过滤波器时,这种滤波器叫做高通滤波器。 当允许信号中较低频率的成分通过滤波器时,这种滤波器叫做低通滤波器。 当只允许信号中某个频率范围内的成分通过滤波器时,这种滤波器叫做带通滤波器。 当不允许信号中某个频率范围内的成分通过滤波器时,这种滤波器叫做带阻滤波器.
从统计信号处理的角度,降噪可以看成滤波的一种。降噪的目的在于突出信号本身而抑制噪声影响。从这 个角度,降噪就是给信号一个高的权重而给噪声一个低的权重。维纳滤波就是一个典型的降噪滤波器.
在语音处理过程,先分帧,再在频域分成各个子带处理,处理后转成时域,合成语声。从描述上看, 语音合成就是和分帧相反的过程,保证信号数据经过我们变换处理后能够回到原来的状态。把每帧各个子 带转换成时间序列后相互叠加合成为一帧数据.
语音信号为非平稳信号,其统计属性是随着时间变化的,以汉语为例,一句话中包含很多生母和韵母,不同的拼音,发音的特点很明显是不一样的;但是,语音又具有平稳的属性,比如汉语里的一个声母或者韵母,往往只会持续几十到几百毫秒,这一个发音单元里,语音信号表现出明显的稳定性、规律性,在进行语音识别时,对于一句话识别的过程也是以较小的发音单元(音素、字、字节)为单位进行识别的,因此可以用滑动窗来提取短时片段,也即进行分帧加窗操作.
帧长:一帧语音信号的长度,长度可以用多种方式表示,如果用时间表示,一帧信号通常取在15ms-30ms之间,经验值为25ms(论文上大多数人用)。帧长为25ms的一帧信号指的是时长有25毫秒的语音信号。也可以用信号的采样点数来表示,如果一个信号的采样率为16kHz,则一帧信号由 16kHz * 25ms = 400个采样点组成.
帧移:指的是每次分帧时移动的距离,以第一帧信号的起始点开始移动一个帧移,开始下一帧。同样也可以用两种方式表示,用时间表示,常设为10ms,用采样点表示,16kHz采样率的信号帧移一般为160个采样点.
加窗:分帧后每一帧的开始和结束都会出现间断,因此分割的帧越多,与原始信号的误差就越大,加窗就是为了解决这个问题,使成帧后的信号变得连续,并且每一帧都会表现出周期函数的特性。常见的窗函数有:矩形窗、汉明窗、汉宁窗等,在语音信号处理中,通常使用汉明窗,其公式如下:
首先要根据信号长度、帧移、帧长计算出该信号一共可以分的帧数,帧数的计算公式如下: 帧数 = (信号长度-帧长)➗帧移 +1 具体的分帧操作如下图所示:
加窗操作比较简单,仅需将分帧的每一帧信号一次与窗函数进行相乘即可,其中窗函数可以从numpy里直接调用。 在分帧操作时,会遇到最后剩下的信号长度不够一帧的情况,此时需要将对这一段信号进行补零操作,使之达到一帧的长度,或者可以直接将之抛弃,因为最后一帧处于句子最末尾部分,大部分为静音片段.
以下是实现分帧加窗的具体代码
def enframe(signal, frame_len=frame_len, frame_shift=frame_shift, win=np.hamming(frame_len)):
"""
calculate the number of frames:
frames = (num_samples -frame_len) / frame_shift +1
"""
num_samples = signal.size
num_frames = np.floor((num_samples - frame_len) / frame_shift)+1
# calculate the numbers of frames
frames = np.zeros((int(num_frames),frame_len)) # (num_frames,frame_len)
# Initialize an array for putting the frame signals into it
for i in range(int(num_frames)):
frames[i,:] = signal[i*frame_shift:i*frame_shift + frame_len]
frames[i,:] = frames[i,:] * win
return frames
其中需要注意以下几点:
作者: 野哥李 微信公众号: AI算法学习社 欢迎任何形式的转载,但请务必注明出处。 限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 本文章不做任何商业用途,仅作为自学所用,文章后面会有参考链接,我可能会复制原作者的话,如果介意,我会修改或者删除.
最后此篇关于语音处理加窗分帧的文章就讲到这里了,如果你想了解更多关于语音处理加窗分帧的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
对于一个科学实验,我写了一个turtle.py ,它会打开一个 800x480 的窗口并绘制一个缓慢增长的黑点。 turtle.py以 C:\Users\kaza>python C:\Users\ka
我开发了一个 swing 应用程序,但每次运行应用程序时都会打开一个新窗口。我希望如果一个窗口已经打开,则其他窗口不允许打开。 最佳答案 Here是一个 Java 单一应用实例的例子: A singl
有没有办法检测主进程中 Electron 的结构? process.platform 似乎也在 x64 机器上返回 win32,我没有在文档中找到任何获取架构的选项。 最佳答案 你试过 process
public short[] HanningWindow(short[] signal_in ,int pos ,int size) { for (int i= pos; i < pos+si
我有一个具有这些属性的 Electron 窗口: mainWindow = new BrowserWindow({ width: 800, height: 600, title: "Aqu
我有一个 Ubuntu 工作站,我正在尝试引导一个 Windows 节点。 Windows 节点在端口 2222 上打开了 ssh。我一直在关注 http://docs.opscode.com/plu
我是一名优秀的程序员,十分优秀!