不调包绘制音频语谱图并批量生成语谱图

本文详细介绍了如何使用Python不调用外部库绘制语音的语谱图,包括分帧、加窗、短时傅里叶变换和批量生成语谱图的步骤。通过自定义函数实现,最终与librosa绘制的语谱图进行对比,效果一致。
摘要由CSDN通过智能技术生成

什么是语谱图

语谱图(Spectrogam)是表示语音频谱随时间变化的图形,其实是一个二维的图像,但却能表示三个维度的信息,横坐标表示时间,纵坐标表示频率,颜色的深浅来映射能量的大小。任一给定频率成分在给定时刻的强弱用相应点的灰度或色调的浓淡来表示。颜色深,表示该点的语音能量越强,反之表示该点语音能量较弱。

绘制语谱图首先需要对载入的音频进行分帧和加窗处理,然后进行傅里叶变化,然后求出每一帧所对应的时间刻度,然后再将傅里叶变换后的数据取对数求出能量密度谱,将能量与颜色做一个映射,然后画出图像
在这里插入图片描述

分帧

语音信号是一个准稳态的信号,若把它分成较短的帧,每帧中可将其看做稳态信号,可用处理稳态信号的方法来处理。为了使一帧与另一帧之间的参数能够平稳过渡,应在相邻两帧之间互相有部分重叠。一般情况下,帧长取10 ~ 30ms,所以每秒的帧数约为33 ~ 100帧。帧移与帧长的比值一般取0~1/2。其中设每帧长度为win,后一帧对前一帧的位移量为inc。
在这里插入图片描述

因此设计分帧函数就是在函数名中给三个参数,enframe(x, win, inc),其中x为加载的音频数据,win为帧长,inc为帧移,返回值为分帧后的数据。

代码如下:

#分帧函数
def enframe(x, win, inc=None):
    '''
    :param x: 音频数据
    :param win: 帧长
    :param inc: 帧移
    :return: 分帧后的列表
    '''
    nx = len(x)# 获取音频的长度
    if isinstance(win, list) or isinstance(win, np.ndarray):# 判断win是否为窗函数
        nwin = len(win)
        nlen = nwin  # 帧长=窗长
    elif isinstance(win, int):# 说明没有窗函数,将帧长设置为1
        nwin = 1
        nlen = win  # 设置为帧长
    if inc is None:# 帧移不为空则传给nlen
        inc = nlen
    nf = (nx - nlen + inc) // inc# 算出有多少帧
    frameout = np.zeros((nf, nlen))# 填充一个零矩阵出来,行为帧,列为帧数据
    indf = np.multiply(inc, np.array([i for i in range(nf)])) # 设置每帧在x中的位移量位置
    for i in range(nf):# 将数据分帧存在frameout中
        frameout[i, :] = x[indf[i]:indf[i] + nlen]
    return frameout

加窗

在语音处理中,经常可以听到对语音进行分帧和加窗的操作,那加窗到底是什么,为什么要加窗呢?语音信号是一种非平稳的时变信号,要进行FFT或其他针对平稳信号而进行的信号处理时就十分困难。加窗和分帧就类似与高等数学中求积分一样,将曲线分成无限个小格,每个格就可以等似为矩形。在语音处理中也是这样,通过分帧和加窗可以把语音信号在一帧内看作是短时平稳的,加窗其实就是对分帧后的每一帧数据 s ( n ) s(n) s(n)分别乘上窗数据 w ( n ) w(n) w(n),从而形成加窗语音信号 s w ( n ) = s ( n ) ∗ w ( n ) s_w(n)=s(n) \ast w(n) sw(n)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值