《语音信号处理试验教程》(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的。使用CSDN博客查看帮助文件:

Python语音基础操作–2.1语音录制,播放,读取
Python语音基础操作–2.2语音编辑
Python语音基础操作–2.3声强与响度
Python语音基础操作–2.4语音信号生成
Python语音基础操作–3.1语音分帧与加窗
Python语音基础操作–3.2短时时域分析
Python语音基础操作–3.3短时频域分析
Python语音基础操作–3.4倒谱分析与MFCC系数
Python语音基础操作–3.5线性预测分析
Python语音基础操作–4.1语音端点检测
Python语音基础操作–4.2基音周期检测
Python语音基础操作–4.3共振峰估计
Python语音基础操作–5.1自适应滤波
Python语音基础操作–5.2谱减法
Python语音基础操作–5.4小波分解
Python语音基础操作–6.1PCM编码
Python语音基础操作–6.2LPC编码
Python语音基础操作–6.3ADPCM编码
Python语音基础操作–7.1帧合并
Python语音基础操作–7.2LPC的语音合成
Python语音基础操作–10.1基于动态时间规整(DTW)的孤立字语音识别试验
Python语音基础操作–10.2隐马尔科夫模型的孤立字识别
Python语音基础操作–11.1矢量量化(VQ)的说话人情感识别
Python语音基础操作–11.2基于GMM的说话人识别模型
Python语音基础操作–12.1基于KNN的情感识别
Python语音基础操作–12.2基于神经网络的情感识别
Python语音基础操作–12.3基于支持向量机SVM的语音情感识别
Python语音基础操作–12.4基于LDA,PCA的语音情感识别

代码可在Github上下载:busyyang/python_sound_open

从人类的发音器官的机理来看,发不同性质的声音时,声道的情况是不同的。此外,声门和声道的相互藕合会形成语音信号的非线性特性。但语音信号特性随着时间变化是很缓慢的,所以可以作出一些合理的假设,将语音信号分为一些相继的短段进行处理,在这些短段中可以认为语音信号特性是不随时间变化的平稳随机过程。通过对发音器官和语音产生机理的分析,语音生成系统理论上分成三个部分,在声门(声带)以下,称为"声门子系统",它负责产生激励震动,是"激励系统";从声门到嘴唇的呼气通道是声道,是"声道系统";话音从嘴唇辐射出去,因此嘴唇以外部分称为"辐射系统" 。

  • 激励模型

发浊音时,由于声带不断张开与关闭,产生间歇的脉冲波,类似与一个斜三角形的脉冲:
g(n)={12[1−cos⁡(πn/N1)],0⩽n⩽N1cos⁡[π(n−N1)/(2N2)],N1⩽n⩽N1+N20,otherg(n)=\left\{\begin{array}{lc}\frac12\lbrack1-\cos(\pi n/N_1)\rbrack,&0\leqslant n\leqslant N_1\\\cos\lbrack\pi(n-N_1)/(2N_2)\rbrack,&N_1\leqslant n\leqslant N_1+N_2\\0,&other\end{array}\right.g(n)=⎩⎨⎧​21​[1−cos(πn/N1​)],cos[π(n−N1​)/(2N2​)],0,​0⩽n⩽N1​N1​⩽n⩽N1​+N2​other​

其中N1N_1N1​为斜三角上升部分的时间,N1N_1N1​是其下降部分的时间。单个斜三角波波形的频谱G(ejw)G(e^{jw})G(ejw)其z变换的全级模型为:
G(z)=1(1−e−cTz−1)2G(z)=\frac{1}{(1-e^{-cT}z^{-1})^2}G(z)=(1−e−cTz−1)21​

是一个低通滤波器,ccc是一个频率常数。由于G(z)是一个二极点的模型,因此斜三角波形可视为加权的单位脉冲串激励上述单个斜三角波模型的结果。而单位脉冲串及幅值因子则可表示成下面的zzz变换形式:
E(z)=Av1−z−1E(z)=\frac{A_v}{1-z^{-1}}E(z)=1−z−1Av​​

所以整个浊音激励模型为:
U(z)=G(z)E(z)=Av1−z−1⋅1(1−e−cTz−1)2U(z)=G(z)E(z)=\frac{A_v}{1-z^{-1}}·\frac{1}{(1-e^{-cT}z^{-1})^2}U(z)=G(z)E(z)=1−z−1Av​​⋅(1−e−cTz−1)21​

发清音时,元论是发阻塞音或摩擦音,声道都被阻碍形成揣流。所以,可把清音激励模拟为白噪声。

  • 声道模型

共振峰模型把声监视为一个谐振腔,共振峰就是这个腔体的谐振频率。由于人耳昕觉的柯替氏器官的纤毛细胞是按频率感受而排列其位置的,所以这种共振峰的声道模型方法是非常有效的。一般来说,一个元音用前三个共振峰来表示就足够了;而对于较复杂的辅音或鼻音,大概要用到前五个以上的共振峰才行。
从物理声学观点,可以很容易推导出均匀断面的声管的共振频率。一般成人的声道约为17cm 长,因此算出其开口时的共振频率为
Fi=(2i−1)c4LF_i=\frac{(2i-1)c}{4L}Fi​=4L(2i−1)c​

这里,i=1,2,...i=1,2,...i=1,2,...为正整数,表示共振峰的序号; C 为声速; L 为声管长度。可以计算出元音eee前3个振锋为F1=500Hz,F2=1500Hz,F3=2500HzF_1=500Hz,F_2=1500Hz,F_3=2500HzF1​=500Hz,F2​=1500Hz,F3​=2500Hz。另外,除了共振峰频率之外,共振峰模型还包括共振峰带宽和幅度等参数。
对于级联型的共振峰模型来说,声道可以视为一组串联的二阶谐振器。从共振峰理论来看,整个声道具有多个谐振频率和反谐振频率,所以可被模拟为一个包含零极点的数学模型;但对于一般元音,则用全极点模型即可,其传输函数可表示为
V(z)=G1−∑k=1Nakz−kV(z)=\frac{G}{1-\sum\limits_{k=1}^Na_kz^{-k}}V(z)=1−k=1∑N​ak​z−kG​

式巾, NNN是极点个数;GGG是幅值因子;aka_kak​是常系数。此时可将它分解为多个二阶极点的网络的串联,即

V(z)=∏i=1Nai1−biz−1−ciz−2V(z)=\prod_{i=1}^N\frac{a_i}{1-b_iz^{-1}-c_iz^{-2}}V(z)=i=1∏N​1−bi​z−1−ci​z−2ai​​

其中,
ci=−exp⁡(−2πBiT)c_i=-\exp (-2\pi B_iT)ci​=−exp(−2πBi​T)

bi=2exp⁡(−πBiT)cos⁡(2πFiT)b_i=2\exp(-\pi B_iT)\cos(2\pi F_iT)bi​=2exp(−πBi​T)cos(2πFi​T)

ai=1−bi−cia_i=1-b_i-c_iai​=1−bi​−ci​

G=a1⋅a2⋅...aMG=a_1·a_2·...a_MG=a1​⋅a2​⋅...aM​

并且MMM是小于(N+1)/2(N+1)/2(N+1)/2的整数,若zkz_kzk​是第kkk个极点,有zk=e−BkTe−2πFkTz_k=e^{-B_kT}e^{-2\pi F_kT}zk​=e−Bk​Te−2πFk​T,TTT是采样周期。

import pyaudio
import wave
import librosa
import librosa.display
import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
import pandas as pd
from scipy.signal import lfilterclass soundBase:def __init__(self, path):self.path = pathdef audiorecorder(self, len=2, formater=pyaudio.paInt16, rate=16000, frames_per_buffer=1024, channels=2):"""使用麦克风进行录音2020-2-25   Jie Y.  Init:param len: 录制时间长度(秒):param formater: 格式:param rate: 采样率:param frames_per_buffer::param channels: 通道数:return:"""p = pyaudio.PyAudio()stream = p.open(format=formater, channels=channels, rate=rate, input=True, frames_per_buffer=frames_per_buffer)print("start recording......")frames = []for i in range(0, int(rate / frames_per_buffer * len)):data = stream.read(frames_per_buffer)frames.append(data)print("stop recording......")stream.stop_stream()stream.close()p.terminate()wf = wave.open(self.path, 'wb')wf.setnchannels(channels)wf.setsampwidth(p.get_sample_size(formater))wf.setframerate(rate)wf.writeframes(b''.join(frames))wf.close()def audioplayer(self, frames_per_buffer=1024):"""播放语音文件2020-2-25   Jie Y.  Init:param frames_per_buffer::return:"""wf = wave.open(self.path, 'rb')p = pyaudio.PyAudio()stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),channels=wf.getnchannels(),rate=wf.getframerate(),output=True)data = wf.readframes(frames_per_buffer)while data != b'':stream.write(data)data = wf.readframes(frames_per_buffer)stream.stop_stream()stream.close()p.terminate()def audiowrite(self, data, fs, binary=True, channel=1, path=[]):"""信息写入到.wav文件中:param data: 语音信息数据:param fs: 采样率(Hz):param binary: 是否写成二进制文件(只有在写成二进制文件才能用audioplayer播放):param channel: 通道数:param path: 文件路径,默认为self.path的路径:return:"""if len(path) == 0:path = self.pathif binary:wf = wave.open(path, 'wb')wf.setframerate(fs)wf.setnchannels(channel)wf.setsampwidth(2)wf.writeframes(b''.join(data))else:wavfile.write(path, fs, data)def audioread(self, formater='sample'):"""读取语音文件2020-2-26   Jie Y.  Init这里的wavfile.read()函数修改了里面的代码,返回项return fs, data 改为了return fs, data, bit_depth如果这里报错,可以将wavfile.read()修改。:param formater: 获取数据的格式,为sample时,数据为float32的,[-1,1],同matlab同名函数. 否则为文件本身的数据格式指定formater为任意非sample字符串,则返回原始数据。:return: 语音数据data, 采样率fs,数据位数bits"""fs, data, bits = wavfile.read(self.path)if formater == 'sample':data = data / (2 ** (bits - 1))return data, fs, bitsdef soundplot(self, data=[], sr=16000, size=(14, 5)):"""将语音数据/或读取语音数据并绘制出来2020-2-25   Jie Y.  Init:param data: 语音数据:param sr: 采样率:param size: 绘图窗口大小:return:"""if len(data) == 0:data, fs = self.audioread()plt.figure(figsize=size)x = [i / sr for i in range(len(data))]plt.plot(x, data)plt.xlim([0, len(data) / sr])plt.xlabel('s')plt.show()def sound_add(self, data1, data2):"""将两个信号序列相加,若长短不一,在短的序列后端补零:param data1: 序列1:param data2: 序列2:return:"""if len(data1) < len(data2):tmp = np.zeros([len(data2)])for i in range(len(data1)):tmp[i] += data1[i]return tmp + data2elif len(data1) > len(data2):tmp = np.zeros([len(data1)])for i in range(len(data2)):tmp[i] += data2[i]return tmp + data1else:return data1 + data2def SPL(self, data, fs, frameLen=100, isplot=True):"""计算声压曲线2020-2-26   Jie Y.  Init:param data: 语音信号数据:param fs: 采样率:param frameLen: 计算声压的时间长度(ms单位):param isplot: 是否绘图,默认是:return: 返回声压列表spls"""def spl_cal(s, fs, frameLen):"""根据数学公式计算单个声压值$y=\sqrt(\sum_{i=1}^Nx^2(i))$2020-2-26   Jie Y. Init:param s: 输入数据:param fs: 采样率:param frameLen: 计算声压的时间长度(ms单位):return: 单个声压数值"""l = len(s)M = frameLen * fs / 1000if not l == M:exit('输入信号长度与所定义帧长不等!')# 计算有效声压pp = 0for i in range(int(M)):pp += (s[i] * s[i])pa = np.sqrt(pp / M)p0 = 2e-5spl = 20 * np.log10(pa / p0)return spllength = len(data)M = fs * frameLen // 1000m = length % Mif not m < M // 2:# 最后一帧长度不小于M的一半data = np.hstack((data, np.zeros(M - m)))else:# 最后一帧长度小于M的一半data = data[:M * (length // M)]spls = np.zeros(len(data) // M)for i in range(length // M - 1):s = data[i * M:(i + 1) * M]spls[i] = spl_cal(s, fs, frameLen)if isplot:plt.subplot(211)plt.plot(data)plt.subplot(212)plt.step([i for i in range(len(spls))], spls)plt.show()return splsdef iso226(self, phon, isplot=True):"""绘制等响度曲线,输入响度phon2020-2-26   Jie Y.  Init:param phon: 响度值0~90:param isplot: 是否绘图,默认是:return:"""## 参数来源: 语音信号处理试验教程,梁瑞宇P36-P37f = [20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, \1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500]af = [0.532, 0.506, 0.480, 0.455, 0.432, 0.409, 0.387, 0.367, 0.349, 0.330, 0.315, \0.301, 0.288, 0.276, 0.267, 0.259, 0.253, 0.250, 0.246, 0.244, 0.243, 0.243, \0.243, 0.242, 0.242, 0.245, 0.254, 0.271, 0.301]Lu = [-31.6, - 27.2, - 23.0, - 19.1, - 15.9, - 13.0, - 10.3, - 8.1, - 6.2, - 4.5, - 3.1, \- 2.0, - 1.1, - 0.4, 0.0, 0.3, 0.5, 0.0, - 2.7, - 4.1, - 1.0, 1.7, \2.5, 1.2, - 2.1, - 7.1, - 11.2, - 10.7, - 3.1]Tf = [78.5, 68.7, 59.5, 51.1, 44.0, 37.5, 31.5, 26.5, 22.1, 17.9, 14.4, \11.4, 8.6, 6.2, 4.4, 3.0, 2.2, 2.4, 3.5, 1.7, - 1.3, - 4.2, \- 6.0, - 5.4, - 1.5, 6.0, 12.6, 13.9, 12.3]if phon < 0 or phon > 90:print('Phon value out of range!')spl = 0freq = 0else:Ln = phon# 从响度级计算声压级Af = 4.47E-3 * (10 ** (0.025 * Ln) - 1.15) + np.power(0.4 * np.power(10, np.add(Tf, Lu) / 10 - 9), af)Lp = np.multiply(np.divide(10, af), np.log10(Af)) - Lu + 94spl = Lpfreq = fif isplot:plt.semilogx(freq, spl, ':k')plt.axis([20, 20000, -10, 130])plt.title('Phon={}'.format(phon))plt.grid()plt.show()return spl, freqdef vowel_generate(self, len, pitch=100, sr=16000, f=[730, 1090, 2440]):"""生成一个元音片段2020-2-26   Jie Y.  Init:param len: 长度,点数:param pitch::param sr: 采样率:param f: 前3个共振峰,默认为元音a的:return: 生成的序列"""f1, f2, f3 = f[0], f[1], f[2]y = np.zeros(len)points = [i for i in range(0, len, sr // pitch)]indices = np.array(list(map(int, np.floor(points))))y[indices] = (indices + 1) - pointsy[indices + 1] = points - indicesa = np.exp(-250 * 2 * np.pi / sr)y = lfilter([1], [1, 0, -a * a], y)if f1 > 0:cft = f1 / srbw = 50q = f1 / bwrho = np.exp(-np.pi * cft / q)theta = 2 * np.pi * cft * np.sqrt(1 - 1 / (4 * q * q))a2 = -2 * rho * np.cos(theta)a3 = rho * rhoy = lfilter([1 + a2 + a3], [1, a2, a3], y)if f2 > 0:cft = f2 / srbw = 50q = f2 / bwrho = np.exp(-np.pi * cft / q)theta = 2 * np.pi * cft * np.sqrt(1 - 1 / (4 * q * q))a2 = -2 * rho * np.cos(theta)a3 = rho * rhoy = lfilter([1 + a2 + a3], [1, a2, a3], y)if f3 > 0:cft = f3 / srbw = 50q = f3 / bwrho = np.exp(-np.pi * cft / q)theta = 2 * np.pi * cft * np.sqrt(1 - 1 / (4 * q * q))a2 = -2 * rho * np.cos(theta)a3 = rho * rhoy = lfilter([1 + a2 + a3], [1, a2, a3], y)plt.plot(y)plt.show()return y
from soundBase import soundBasesb = soundBase('a.wav')
y = sb.vowel_generate(16000)
sb.audiowrite(y, 16000)
sb.soundplot()
sb.audioplayer()

Python语音基础操作--2.4语音信号生成相关推荐

  1. python自相关函数提取基音周期_Python语音基础操作--4.2基音周期检测

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  2. Python语音基础操作--4.3共振峰估计

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  3. Python语音基础操作--11.2基于GMM的说话人识别模型

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  4. Python语音基础操作--6.3ADPCM编码

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  5. Python语音基础操作--2.3声强与响度

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  6. Python语音基础操作--10.2隐马尔科夫模型的孤立字识别

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  7. Python语音基础操作--5.1自适应滤波

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  8. Python语音基础操作--10.1基于动态时间规整(DTW)的孤立字语音识别试验

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  9. Python语音基础操作--3.5线性预测分析

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

  10. Python语音基础操作--3.2短时时域分析

    <语音信号处理试验教程>(梁瑞宇等)的代码主要是Matlab实现的,现在Python比较热门,所以把这个项目大部分内容写成了Python实现,大部分是手动写的.使用CSDN博客查看帮助文件 ...

最新文章

  1. java学习笔记(一) ----java下常用的包功能
  2. TensorFlow和深度学习-无需博士学位(TensorFlow and deep learning without a PhD)
  3. Cheatsheet: 2010 04.26 ~ 04.30
  4. windows系统nexus3安装和配置
  5. linux-01-linux中的一些特殊符号
  6. 如何限制修改IP地址
  7. IO标准库类型之间的关系
  8. Mac 10.12使用free命令(fish)
  9. 22.docker wait
  10. python内置的字典dict中元素_Python内置字典;dict ,set
  11. 【locust】locust与jmeter性能对比
  12. 【编译原理·总复习】第二章||文法语言||语法树||最左最右推导归约||句柄直接短语||例题+知识点
  13. 头条号自媒体运营:如何在今日头条涨500+粉丝?
  14. 快衰落,慢衰落,大尺度衰落,小尺度衰落的关系
  15. python什么意思g_在外行人看来,Python字符串格式“g”实际意味着什么?
  16. mysql 留存率_mysql查询用户留存语法(用户留存和用户留存率问题)
  17. 【杂货铺】中国房屋种类
  18. 含文档+PPT+源码等]精品微信小程ssm便捷记账本小程序+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
  19. Microsoft Teams 会议室讲解
  20. spring boot手工DIY网站毕业设计源码310226

热门文章

  1. 黑苹果 U盘刻录工具Transmac与Etcher使用
  2. 在线供应链管理系统一体化解决方案,整合B2B上下游供应资源
  3. 计算机中文件无法删除,电脑文件无法删除怎么办?强制删除文件的方法
  4. 联想Thinkpad sl400 7HC入手感觉
  5. sl400上面安装ubuntu
  6. 东芝打印机共享怎么设置_东芝网络打印机怎么安装
  7. c语言1117查找数组元素,路雪军 Carl
  8. 情人节程序员用HTML网页表白【新婚快乐】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
  9. Python程序设计实验——2.掷骰子游戏
  10. indows蓝屏PROCESS1_INITIALIZATION_FAILED STOP:0x0000006B 解决方法