Python语音基础操作–6.1PCM编码

2023-09-24 25 0

《语音信号处理试验教程》(梁瑞宇等)的代码主要是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语音基础操作–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

脉冲编码调制(Pulse Code Modulation, PCM)是语音信号的重要编码方式之一。语音编码是将模拟信号转为数字信号的语音通信技术,分为波形编码、参量编码和混合编码等类型。波形编码针对语音波形进行,在降低量化样本比特数的同时保持了良好的语音质量。PCM编码就是一种波形编码方法,通过每隔一段时间对模拟语音信号采样,将其取整量化,用二进制码表示抽样量化的隔值,实现将语音数字化的编码调制。
PCM是现代数字传输系统普遍采用的调制方式。PCM可以向用户提供多种业务,包括2M-155Mbit/s速率的数字数据专线业务和语音、图像、远程教学等业务,适用于传输速率要求高、需要更高带宽的应用,在语音信号处理中有着广泛的运用。PCM 分为抽样、量化和编码三个步骤。

在这里插入图片描述
抽样过程就是抽取某点的频率值的过程。显然,在1 s 内抽取的点越多,获取的频率信息越丰富。为了复原波形, 一次振动中必须有2 个点的采样,人耳能够感觉到的最高频率为20 kHz ,因此要满足人耳的听觉要求,则需要至少每秒进行40000 次采样,即采样率为44.1 kHz 。光有频率信息是不够的,还必须获得该频率的能量值并量化,用于表示信号强度。量化电平数为2 的整数次幕,常用16 bit 的采样大小即 2 16 2^{16} 216。例如对一个语音信号进行8次采样,采样点分别对应的能量值分别为A1-A8,使用2 bit的采样大小只能保留A1-A8中4个点,而进行3 bit的采样则刚好记录下8 点的所有信息。采样率和采样大小的值越大,记录的波形越接近原始信号。

抽样量化就是常规A/D的过程,量化后的抽样信号在一定范围内仅有有限个可取的样值,且信号正负幅度分布的对称性使正负样值个数相等,若将有限个量化样值绝对值从小到大排列,依次赋予十进制数字,以﹢、﹣号为前缀,则量化后的抽样信号就转化为按时序排列的十进制数字码流。将数字转化为二进制编码,根据十进制代码总个数确定二进制位数,即字长。这样将量化的抽样信号变成给定字长的二进制码流的过程就是编码。

import numpy as npdef PCM_encode(x):n = len(x)out = np.zeros((n, 8))for i in range(n):# 符号位if x[i] > 0:out[i, 0] = 1else:out[i, 0] = 0# 数据位if abs(x[i]) < 32:out[i, 1], out[i, 2], out[i, 3], step, st = 0, 0, 0, 2, 0elif abs(x[i]) < 64:out[i, 1], out[i, 2], out[i, 3], step, st = 0, 0, 1, 2, 32elif abs(x[i]) < 128:out[i, 1], out[i, 2], out[i, 3], step, st = 0, 1, 0, 4, 64elif abs(x[i]) < 256:out[i, 1], out[i, 2], out[i, 3], step, st = 0, 1, 1, 8, 128elif abs(x[i]) < 512:out[i, 1], out[i, 2], out[i, 3], step, st = 1, 0, 0, 16, 256elif abs(x[i]) < 1024:out[i, 1], out[i, 2], out[i, 3], step, st = 1, 0, 1, 32, 512elif abs(x[i]) < 2048:out[i, 1], out[i, 2], out[i, 3], step, st = 1, 1, 0, 64, 1024else:out[i, 1], out[i, 2], out[i, 3], step, st = 1, 1, 1, 128, 2048if abs(x[i]) >= 4096:out[i, 1:] = np.array([1, 1, 1, 1, 1, 1])else:tmp = bin(int((abs(x[i]) - st) / step)).replace('0b', '')tmp = '0' * (4 - len(tmp)) + tmpt = [int(k) for k in tmp]out[i, 4:] = treturn out.reshape(8 * n)def PCM_decode(ins, v):inn = ins.reshape(len(ins) // 8, 8)slot = np.array([0, 32, 64, 128, 256, 512, 1024, 2048])step = np.array([2, 2, 4, 8, 16, 32, 64, 128])out = np.zeros(len(ins) // 8)for i in range(inn.shape[0]):sgn = 2 * inn[i, 0] - 1tmp = int(inn[i, 1] * 4 + inn[i, 2] * 2 + inn[i, 3])st = slot[tmp]dt = (inn[i, 4] * 8 + inn[i, 5] * 4 + inn[i, 6] * 2 + inn[i, 7]) * step[tmp] + 0.5 * step[tmp]out[i] = sgn * (st + dt) / 4096 * vreturn out
from chapter2_基础.soundBase import *
from chapter6_语音编码.PCM import *plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = Falsedata, fs = soundBase('C6_1_y.wav').audioread()sxx = np.array(list(map(int, data * 4096)))y = PCM_encode(sxx)yy = PCM_decode(y, 1)plt.subplot(3, 1, 1)
plt.plot(data)
plt.title('编码前')plt.subplot(3, 1, 2)
plt.plot(yy)
plt.title('解码后')plt.subplot(3, 1, 3)
plt.plot(yy - data)
plt.title('误差')plt.savefig('images/pcm.png')
plt.close()

在这里插入图片描述

代码编程
赞赏

相关文章

oracle 坏块问题
修改默认的undo_retention参数设置
使用dbv和RMAN检查数据文件中的坏块
aix6.1上安装10g r2注意事项
AIX存储LV PV VG
客户投诉类网络舆情应对分析