语音信号处理基础知识

1.均值

1.1.均值公式定义

x‾=x1+x2+⋯+xnn=∑j=1nxjn\overline{x} = \frac{x_1 + x_2 + \cdots + x_n}{n} = \frac{\sum^{n}_{j=1}x_j}{n} x=nx1​+x2​+⋯+xn​​=n∑j=1n​xj​​

1.2.物理意义

一段语音信号的均值代表了语音的直流分量, 正常情况下音频系统的输入输出不存在交流分量。 如果发生了直流偏执的现象, 需要在信号预处理阶段去除直流分量。

1.3.代码实现

读取一段新闻语音文件, 计算它的均值。

from scipy.io import wavfile
import numpy as npframerate, data = wavfile.read('./source.wav')
data_len = len(data)
sum = 0
for i in range(data_len):sum += data[i]
mean_data = sum / data_len
print('mean of audio : %f' % mean_data)
mean of audio : -0.000320

numpy提供average函数来计算均值, 效果一致。

np.average(data)
-0.000320226621917049

可以看出, 均值接近0.

2.方差

2.1.方差的公式定义

s2=1n∑i=1n(xi−x‾)2s^2 = \frac{1}{n}\sum_{i=1}^{n}(x_i - \overline{x})^2 s2=n1​i=1∑n​(xi​−x)2

2.2.物理意义

方差描述语音信号的波动范围, 交流分量的强弱, 即交流信号的平均功率。

2.3.代码实现

sum = 0
for i in range(data_len):sum += (data[i] - mean_data) ** 2
var_data = sum / data_len
print('var of audio : %f' % var_data)
var of audio : 3197990.844967

numpy提供var函数用以计算方差, 效果一致。

np.var(data)
3197990.8449671054

3.均方差

3.1.均方差的公式定义

σ=1n∑i=1n(xi−x‾)2σ = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(x_i - \overline{x})^2} σ=n1​i=1∑n​(xi​−x)2​

3.2.物理意义

均方差等于方差的方根, 和方差一样可以反映语音信号的离散程度。由于方差的平方计算造成量纲的倍数变化无法直观反映出偏离程度, 均方差的意义更为直观。

3.3.代码实现

sum = 0
for i in range(data_len):sum += (data[i] - mean_data) ** 2
rmse_data = np.sqrt(sum / data_len)
print('rmse of data : %f' % rmse_data)
rmse of data : 1788.292718

numpy提供std函数用以计算均方差, 效果一致。

np.std(data)
1788.2927179203928

4.协方差

4.1.公式定义

Cov(X,Y)=∑i=0n(X−X‾)(Y−Y‾)n−1Cov(X, Y) = \frac{\sum_{i=0}^{n}(X-\overline{X})(Y - \overline{Y})}{n-1}Cov(X,Y)=n−1∑i=0n​(X−X)(Y−Y)​

4.2.物理意义

描述两个变量之间的变化趋势相关性

4.3.代码仿真理解

计算初始相位0, π之间的正弦信号和初始相位为0的正弦信号之间的协方差。

def cov(x, y):avr_x = np.average(x)avr_y = np.average(y)sum = 0for i in range(len(x)):sum += (x[i] - avr_x) * (y[i] - avr_y)return sum / (len(x) - 1)
import matplotlib.pyplot as pltx = np.arange(0, 10 * np.pi, 0.1)
y_1 = np.sin(x)
plt.plot(x, y_1)
plt.xlabel('sample (n)')
plt.ylabel('amp')
plt.show()

上图绘制的是初始相位为0的正弦信号图像

y_2 = np.sin(x + np.pi)
plt.plot(x, y_2)
[<matplotlib.lines.Line2D at 0x7efef0fbd2b0>]

上图绘制的是初始相位为π的正弦信号图像,可以看出相位相差π的两个序列的变化趋势完全相反。计算这两个信号序列的协方差

print(cov(y_1, y_2))
-0.5002531220184325

numpy提供cov函数来计算协方差矩阵, 矩阵的次对角线是两个序列的协方差。

np.cov(y_1, y_2)
array([[ 0.50025312, -0.50025312],[-0.50025312,  0.50025312]])

计算不同初始相位下, 两个正弦序列的协方差变化情况。

phi_list = np.linspace(0, 2 * np.pi, 100)
cov_list = [cov(np.sin(x), np.sin(x + phi)) for phi in phi_list]
plt.plot(phi_list, cov_list)
[<matplotlib.lines.Line2D at 0x7efef0af0208>]

5.分帧加窗以及频谱泄露

5.1.频谱泄露

计算离散傅里叶变换的前提是假设输入有限长度的信号序列是一个周期信号的一个完整周期, 周期长度为该序列的长度。离散傅里叶变换本质是以该序列长度为周期进行周期延拓后的周期信号, 计算这个无限周期序列的频谱图。由于dft计算出的频谱对应的是周期延拓后的周期信号, 如果有限长的信号的首尾不相等, 会使得周期延拓后的周期信号不连贯, 会带来一些本来不属于信号本身的频率分量。

下面定义dft实现如下:

import mathdef dft(x):""":bref 计算输入序列的离散傅里叶变换:param x : 输入序列:param N : dft长度N:return spectrum : 频谱"""N = len(x)spec = np.zeros(N)for k in range(N):sum = 0for n in range(N):sum += x[n] * np.exp(-1j * 2 * np.pi * n * k / N)spec[k] = abs(sum / N)return spec

定义计算频谱对应的频率值函数:

def dft_freq(N, sample_rate):""":bref 计算对应的频域分辨率:param N : DFT点数:param sample_rate : 采样率:return freqs : 对应的频域的采样率"""freqs = sample_rate / N * np.array(range(N))return freqs

采用频率为10的正弦信号, 使用五个整数倍周期作为信号的长度; 从绘制的波形图可以看出整数倍周期的首尾是连贯的。

def create_sin(Ts, freq, times):sample_rate = 1 / Tsfreq = 10T = 1 / freqduration = times * Tsamples = math.ceil(duration / Ts)t = Ts * np.array(range(samples))x = np.cos(2 * np.pi * freq * t)return t, x
Ts = 0.01
t, x = create_sin(Ts, 10, 5)
plt.plot(t, x)
[<matplotlib.lines.Line2D at 0x7efeef8ec5c0>]

将该信号进行周期延拓三次, 可以看出周期延拓后的信号和原本一致。

def sig_append(x, times, Ts):""":bref 周期延拓:param x : 需要周期延拓的信号:param times : 延拓次数:param Ts : 采样周期:return t_add : 延拓后序列的时间:return x_add : 延拓后的信号幅值"""N = x.shape[0]t_add = Ts * np.array(range(N * times))x_add = np.zeros(N * times)for i in range(times):x_add[i * N:(i + 1) * N] = x[:]return t_add, x_add
t_add, x_add = sig_append(x, 3, Ts)
plt.plot(t_add, x_add)
[<matplotlib.lines.Line2D at 0x7efeef56d860>]

使用dft计算该信号频谱, 可以看出频谱分量只有10Hz。

freq_dft = dft_freq(x.shape[0], 1 / Ts)
plt.plot(freq_dft, dft(x))
plt.xlabel('Freq (Hz)')
plt.xlim([0, freq_dft[-1] / 2])
plt.show()

将信号长度改为非整数倍周期5.2, 来看看时域频域的效果。

t_5_2, x_5_2 = create_sin(0.01, 10, 5.2)
plt.plot(t_5_2, x_5_2)
[<matplotlib.lines.Line2D at 0x7efeec7f6908>]

同样的, 将周期进行三倍延拓看看效果。可以发现在延拓交界点存在不期望的波形。

t_add, x_add = sig_append(x_5_2, 3, Ts)
plt.plot(t_add, x_add)
[<matplotlib.lines.Line2D at 0x7efeed7d9cf8>]

来看看频域的效果, 可以发现在10Hz分量之外还有其他的频率分量, 整个信号的能量从基频泄露了一部分到其他频率上, 这就是频谱泄露。

freq_dft = dft_freq(x_10_1.shape[0], 1 / Ts)
plt.plot(freq_dft, dft(x_10_1))
plt.xlabel('Freq (Hz)')
plt.xlim([0, freq_dft[-1] / 2])
plt.show()

可以通过对信号的首尾进行抑制来减弱首尾不连贯带来的频谱泄露, 即就是加窗。
汉宁窗的数学定义是:

w(n)=0.5×(1−cos(2πn/(N−1))),0≤n≤N−1w(n) = 0.5 × (1 - cos(2\pi n / (N - 1))), 0 \le n \le N - 1w(n)=0.5×(1−cos(2πn/(N−1))),0≤n≤N−1

定义生成汉宁窗的函数如下:

def create_hanning(N):window = np.arange(N)window = (1 - np.cos(window / (N - 1) * 2 * np.pi) + 1) / 2return window

对5.2倍周期的信号进行汉宁窗加权, 可以看到首尾的信号被衰减了。

window = create_hanning(x_5_2.shape[0])
x_5_2_window = x_5_2 * window
plt.figure(0)
plt.title('hanning window')
plt.plot(range(window.shape[0]), window)
plt.figure(1)
plt.title('after window')
plt.plot(t_5_2, x_5_2_window)
[<matplotlib.lines.Line2D at 0x7efeec381358>]

绘制对应的频谱图, 可以看出非10Hz的信号分量少了很多。

freq_dft = dft_freq(x_5_2_window.shape[0], 1 / Ts)
plt.plot(freq_dft, dft(x_5_2_window))
plt.xlabel('Freq (Hz)')
plt.xlim([0, freq_dft[-1] / 2])
plt.show()

def frame_sig(sig,frame_len,frame_step,winfunc=lambda x:numpy.ones((x,))):""":bref 将信号进行分帧加窗处理:param sig: 需要分帧加窗的语音信号.:param frame_len: 帧长.:param frame_step: 帧移.:param winfunc: 窗函数, 默认为矩形窗.:returns: 分帧后的数据."""slen = len(sig)frame_len = int(round_half_up(frame_len))frame_step = int(round_half_up(frame_step))if slen <= frame_len:numframes = 1else:numframes = 1 + int(math.ceil((1.0*slen - frame_len)/frame_step))padlen = int((numframes-1)*frame_step + frame_len)zeros = numpy.zeros((padlen - slen,))padsignal = numpy.concatenate((sig,zeros))indices = numpy.tile(numpy.arange(0,frame_len),(numframes,1)) + numpy.tile(numpy.arange(0,numframes*frame_step,frame_step),(frame_len,1)).Tindices = numpy.array(indices,dtype=numpy.int32)frames = padsignal[indices]win = numpy.tile(winfunc(frame_len),(numframes,1))return frames*winnp.fft.fft
<function numpy.fft.fft(a, n=None, axis=-1, norm=None)>

音频信号处理基础知识相关推荐

  1. 音频开发基础知识简介

    在现实生活中,音频(audio)主要用在两大场景中:语音(voice)和音乐(music).语音主要用于沟通通信,如打电话,现在由于语音识别的发展,人机语音交互也是语音的一个应用,目前正在风口上,好多 ...

  2. 视音频格式基础知识视频压缩

    视音频格式基础知识&视频压缩 2018.7.10 一.视频基础知识 1.什么是视频:连续的图像变化每秒超过24帧(frame)画面以上时,根据视觉暂留原理,人眼无法辨别单幅的静态画面:看上去是 ...

  3. 计算机播放声音时进行模数转换,音频的基础知识.ppt

    文档介绍: 数字音频的基础知识Szsy-luowei-2006音频的分类数字音频的产生数字音频文件的分类数字音频信息获取的途径摔尾表帛阜姚矫咐褒睡阀俘疵师哀哮沁魂休霹辱鹰娱却扑遭音舟诣厕二淡音频的基础 ...

  4. 声纹技术(二):音频信号处理基础【模拟信号(连续)--采样-->数字信号(离散)--量化-->振幅简化为整数--编码-->二进制序列】【WAV音频格式】【SoX】【分帧-加窗-】

    2.1 欲懂声纹,先学音频 从学科分类上讲,声纹技术是语音信号处理的一个分支,而语音信号处理则属于音频信号处理这个大类. 语音信号和音频信号,这二者的区别在于: 语音信号专指人类说话时所发出的具有社会 ...

  5. 搞语音的有关音频的基础知识

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 一.声音的由来 声音是一种波,由物体振动产生的,必须通过介质传播(固.液.气).通常是人们听的到语音是由空气传播的,是一种纵波, ...

  6. 音频相关基础知识(采样率、位深度、通道数、PCM、AAC)

    (这其实是一篇转载好几篇的博客,然后自己加了少许) 转载博客1 关于采样率&位深&码率&无损的一些心得_Marenow的博客-CSDN博客_flac格式采样率比特率记笔记,记下 ...

  7. ios音频相关基础知识

    最近在看音频相关的知识,然后就搜集了些基础知识记录下来,以便日后查看和供需要的人学习 1.音频(audio) 指人耳可以听到的声音频率在20HZ~20kHz之间的声波,称为音频. 2.音频采样(aud ...

  8. 计算机基础知识 音频,计算机基础知识(总结+试题).pdf

    计算机基础知识(总结+试题) 第一册 Windows XP 第 1 章计算机基本基础 P14 1, 计算机有什么特性 计算机是一种不需要人的直接干预而能够对各种数字化信息进行算术和逻辑运 行的快速工具 ...

  9. Android Multimedia框架总结(十七)音频开发基础知识

    原文链接:http://blog.csdn.net/hejjunlin/article/details/53078828 近年来,唱吧,全民K歌,QQ音乐,等成为音频软件的主流力量,音频开发一直是多媒 ...

最新文章

  1. 关于VC中的Timer
  2. 少量数据训练语音识别的思路
  3. python实现三叉树_使用python代码实现三叉搜索树高效率”自动输入提示”功能
  4. Python3 pymysql连接mysql数据库 windows
  5. Merge Sorted Array
  6. 怎么确保一个集合不能被修改
  7. html文件中包含相关的d3.js文件,D3.js进阶系列之CSV表格文件的读取详解
  8. hash表、java中的hashMap/hashSet
  9. 智能网联汽车云控系统第2部分:车云数据交互规范
  10. WINDOWS游戏编程学习笔记(一):Hello Game!
  11. 计算机等级考试Excel总成绩,计算机等级考试EXCEL练习题-6公务员考试成绩表
  12. puppeteer实现百度贴吧自动签到
  13. Transformer解析与tensorflow代码解读
  14. SyntaxError报错成功解决
  15. Linux查看端口命令:netstat -tln
  16. 旅行商问题 Traveling Salesman Problem(TSP)
  17. glColor3f函数颜色
  18. 1130. 【NOIP2005PJ】循环
  19. Dubbo (五) ---------监控中心
  20. 如何做内网穿透,在家里连回公司服务器做操作

热门文章

  1. [经验教程]iPhone苹果手机Siri怎么设置?
  2. 神经网络入门及tensorflow实战
  3. struts2学习之表单校验的两种方式
  4. C++包扩展_皇帝乞丐一念间!USB TypeC接口的扩展差异咋就这么大呢?
  5. 面试官:今天还是来聊聊CMS垃圾收集器呗?
  6. Synopsys验证VIP学习笔记(6)检查和打印信息控制
  7. linux的v4l2运行源码,linux v4l2摄像头应用层编程介绍
  8. 两台外网计算机远程桌面访问(内网穿透)
  9. SetTimer的使用
  10. CSS Sprites 样式生成工具