• 如果您觉得本站非常有看点，那么赶紧使用Ctrl+D 收藏吧

音频信号处理基础知识

1周前 (10-17) 13次浏览

语音信号处理基础知识

1.均值

1.1.均值公式定义

x

=

x

1

+

x

2

+

+

x

n

n

=

j

=

1

n

x

j

n

overline{x} = frac{x_1 + x_2 + cdots + x_n}{n} = frac{sum^{n}_{j=1}x_j}{n}

x=nx1+x2++xn=nj=1nxj

1.3.代码实现

``````from scipy.io import wavfile
import numpy as np

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
``````

2.方差

2.1.方差的公式定义

s

2

=

1

n

i

=

1

n

(

x

i

x

)

2

s^2 = frac{1}{n}sum_{i=1}^{n}(x_i – overline{x})^2

s2=n1i=1n(xix)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.均方差的公式定义

σ

=

1

n

i

=

1

n

(

x

i

x

)

2

σ = sqrt{frac{1}{n}sum_{i=1}^{n}(x_i – overline{x})^2}

σ=n1i=1n(xix)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.公式定义

C

o

v

(

X

,

Y

)

=

i

=

0

n

(

X

X

)

(

Y

Y

)

n

1

Cov(X, Y) = frac{sum_{i=0}^{n}(X-overline{X})(Y – overline{Y})}{n-1}

Cov(X,Y)=n1i=0n(XX)(YY)

4.3.代码仿真理解

``````def cov(x, y):
avr_x = np.average(x)
avr_y = np.average(y)
sum = 0
for i in range(len(x)):
sum += (x[i] - avr_x) * (y[i] - avr_y)
return sum / (len(x) - 1)
``````
``````import matplotlib.pyplot as plt

x = 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()
``````

``````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.频谱泄露

``````import math

def dft(x):
"""
:bref 计算输入序列的离散傅里叶变换

:param x : 输入序列
:param N : dft长度N
:return spectrum : 频谱
"""
N = len(x)
spec = np.zeros(N)
for k in range(N):
sum = 0
for 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
``````

``````def create_sin(Ts, freq, times):
sample_rate = 1 / Ts
freq = 10
T = 1 / freq
duration = times * T
samples = 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 : 采样周期
"""
N = x.shape[0]
t_add = Ts * np.array(range(N * times))
for i in range(times):
x_add[i * N:(i + 1) * N] = x[:]
``````
``````t_add, x_add = sig_append(x, 3, Ts)
``````
``````[<matplotlib.lines.Line2D at 0x7efeef56d860>]
``````

``````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()
``````

``````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)
``````
``````[<matplotlib.lines.Line2D at 0x7efeed7d9cf8>]
``````

``````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

c

o

s

(

2

π

n

/

(

N

1

)

)

)

,

0

n

N

1

w(n) = 0.5 × (1 – cos(2pi n / (N – 1))), 0 le n le N – 1

w(n)=0.5×(1cos(2πn/(N1))),0nN1

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

``````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>]
``````

``````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 = 1
else:
numframes = 1 + int(math.ceil((1.0*slen - frame_len)/frame_step))

``````<function numpy.fft.fft(a, n=None, axis=-1, norm=None)>
``````