主要记录本小白智能语音处理课程的实验,希望能帮到大家。
实验一 语音信号的读取、预处理及特征提取
实验目的及要求
1、掌握语音信号的读取方法。
2、掌握利用 librosa 实现语音信号读取、显示的功能,掌握对原始语音信号,修改采样率、多通道-单通道转换、去静音、预加重的预处理方法。
3、掌握利用 librosa 实现 log-Spec、log-Fbank、MFCC 特征的提取。
4、掌握利用 matplotlib、librosa 实现语音信号及语音特征可视化的方法。
实验过程及实验结果分析
语音信号的读取
(一)利用自己的手机录制一段语音信号,实现下述功能
(1) 利用 librosa+ffmpeg 实现语音信号的读取,打印采样率、通道数、语音样本数、语音时长信息。
(2) 将输入语音改为单通道、采样率调整为 16000Hz,并将转换后的语音保存成wav 格式。
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
if __name__ == "__main__":
file_wav = 'test1.m4a'
#打印采样率和通道信息
data,fs = librosa.load(file_wav,sr=None,mono=False)
t = librosa.get_duration(y=data, sr=22050, S=None, n_fft=2048, hop_length=512, center=True, filename=None)
print("采样率:",data.shape)
print("时长:",t)
print("通道数:",fs)
#改为单通道,调整采样率并保存
data1,fs1 = librosa.load(file_wav,sr=16000,mono=True)
print("data1:",data1)
print("fs1:",fs1)
sf.write("test2.wav",data1,fs1)
# #读取保存好的文件
data3,fs3 = librosa.load('lsh2.wav',sr=16000)
fig = plt.figure(1)
ax1 = fig.add_subplot(3,1,1)
librosa.display.waveshow(data3,sr=fs3,ax=ax1)
plt.show()
语音信号的显示与去静音处理
(1)读取转换好的 wav 文件,并将 wav 波形显示出来。
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
if __name__ == "__main__":
# #读取保存好的文件
data3,fs3 = librosa.load('test2.wav',sr=16000)
fig = plt.figure(1)
ax1 = fig.add_subplot(3,1,1)
librosa.display.waveshow(data3,sr=fs3,ax=ax1)
plt.show()
(2)去除语音前后的静音,分别设置阈值为 10、30、60dB,并将去静音后的音频文件进行保存。
(3) 绘制去首尾静音前后的音频波形文件对比图。
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
if __name__ == "__main__":
file_wav = 'lsh2.wav'
#静音消除
data,fs = librosa.load(file_wav,sr=16000)
print(len(data))
yt1,index10 = librosa.effects.trim(data,top_db=10)
print("10db",index10)
yt2, index30 = librosa.effects.trim(data, top_db=30)
print("30db", index30)
yt3, index60 = librosa.effects.trim(data, top_db=60)
print("60db", index60)
fig,axs = plt.subplots(nrows=4,ncols=1)
librosa.display.waveshow(data,sr=fs,ax=axs[0])
librosa.display.waveshow(yt1,sr=fs,ax=axs[1])
librosa.display.waveshow(yt2, sr=fs, ax=axs[2])
librosa.display.waveshow(yt3, sr=fs, ax=axs[3])
plt.show()
sf.write('test_trim_10.wav', yt1,fs)
sf.write('test_trim_30.wav', yt2, fs)
sf.write('test_trim_60.wav', yt3, fs)
(4)去除语音中所有的静音,分别设置阈值为 10、30、60dB,并将去静音后的音频文件进行保存。
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
if __name__ == "__main__":
file_wav = 'lsh2.wav'
#消除全部静音
y,fs = librosa.load(file_wav,sr=16000)
#10db
intervals1 = librosa.effects.split(y,top_db=10)
print(intervals1)
y_remix1 = librosa.effects.remix(y,intervals1)
#30db
intervals2 = librosa.effects.split(y, top_db=10)
print(intervals2)
y_remix2 = librosa.effects.remix(y, intervals2)
#60db
intervals3 = librosa.effects.split(y, top_db=10)
print(intervals3)
y_remix3 = librosa.effects.remix(y, intervals3)
#绘图
fig,axs = plt.subplots(nrows=2,ncols=3,sharex=True,sharey=True)
librosa.display.waveshow(y,sr=fs,ax=axs[0][0])
librosa.display.waveshow(y, sr=fs, ax=axs[0][1])
librosa.display.waveshow(y, sr=fs, ax=axs[0][2])
librosa.display.waveshow(y_remix1, sr=fs, ax=axs[1][0],offset=intervals1[0][0]/fs)
librosa.display.waveshow(y_remix2, sr=fs, ax=axs[1][1], offset=intervals2[0][0] / fs)
librosa.display.waveshow(y_remix3, sr=fs, ax=axs[1][2], offset=intervals3[0][0] / fs)
#画分割线
for interval in intervals1:
axs[0][0].vlines(interval[0]/fs,-0.5,0.5,colors='r')
axs[0][0].vlines(interval[1]/fs,-0.5,0.5,colors='r')
for interval in intervals2:
axs[0][1].vlines(interval[0] / fs, -0.5, 0.5, colors='r')
axs[0][1].vlines(interval[1] / fs, -0.5, 0.5, colors='r')
for interval in intervals3:
axs[0][2].vlines(interval[0] / fs, -0.5, 0.5, colors='r')
axs[0][2].vlines(interval[1] / fs, -0.5, 0.5, colors='r')
plt.show()
语音特征的提取
(1)利用实验(一)中生成的 wav 文件,进行 log-Spec 特征的提取并对提取的特征进行显示,打印提取特征的维度.
import librosa
import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
if __name__ == "__main__":
file_wav = 'test2.wav'
y,fs = librosa.load(file_wav,sr=16000)
frame_t = 25
hop_length_t = 10
win_length = int(frame_t*fs/1000)
hop_length = int(hop_length_t*fs/1000)
n_fft = int(2**np.ceil(np.log2(win_length)))
print("nfft:{},win_len:{},hop_len:{}".format(n_fft,win_length,hop_length))
S = np.abs(librosa.stft(y,n_fft=n_fft,hop_length=hop_length,win_length=win_length))
fig = plt.figure()
librosa.display.specshow(S, y_axis='linear', x_axis='time',hop_length=hop_length, sr=fs)
plt.colorbar()
plt.show()
(2)对实验(一)中生成的 wav 文件进行预加重处理后,进行 log-Spec 特征的提取并对提取的特征进行显示。
# 预加重 pre-emphasis
if __name__ == "__main__":
file_wav = 'test2.wav'
y, fs = librosa.load(file_wav, sr=16000)
n_fft = 512
win_length = 512
hop_length = 160
y_filt = librosa.effects.preemphasis(y)
sf.write("test_trim_pre.wav", y_filt, fs)
S = librosa.stft(y, n_fft=n_fft, hop_length=hop_length, win_length=win_length)
S = librosa.amplitude_to_db(np.abs(S))
S_preemp = librosa.stft(y_filt, n_fft=512, hop_length=hop_length, win_length=win_length)
S_preemp = librosa.amplitude_to_db(np.abs(S_preemp))
fig, axs = plt.subplots(2, 1, sharex=True, sharey=True)
librosa.display.specshow(S, sr=fs, hop_length=hop_length, y_axis='linear', x_axis='time', ax=axs[0])
axs[0].set(title='Original signal')
img = librosa.display.specshow(S_preemp, sr=fs, hop_length=hop_length, y_axis='linear', x_axis='time', ax=axs[1])
axs[1].set(title='pre-emphasis signal')
fig.colorbar(img, ax=axs, format="%+2.f dB")
plt.show()
(3)对实验(一)中生成的 wav 文件进行 log-Fbank 特征的提取并设置 滤波器组的数目分别为 40、128。对提取的特征进行显示。
# fbank 特征
#滤波器组
if __name__ == "__main__":
file_wav = 'test2.wav'
y,fs = librosa.load(file_wav,sr=16000)
win_length =512
hop_length = 160
n_fft = 512
n_mels= 40
melfb = librosa.filters.mel(sr=fs, n_fft=n_fft,n_mels = n_mels,htk=True)
print(melfb.shape)
x = np.arange(melfb.shape[1])*fs/n_fft
fig = plt.figure()
plt.plot(x,melfb.T)
plt.show()
fig = plt.figure()
fbank = librosa.feature.melspectrogram(y,
sr = fs,
n_fft = n_fft,
win_length = win_length,
hop_length = hop_length,
n_mels = n_mels)
print(fbank.shape)
fbank_db = librosa.power_to_db(fbank, ref=np.max)
img = librosa.display.specshow(fbank_db, x_axis='time', y_axis='mel', sr=fs,fmax=fs/2,)
fig.colorbar(img,format='%+2.0f dB')
plt.title('Mel-frequency spectrogram')
plt.show()
(4)对实验(一)中生成的 wav 文件进行 MFCC 特征的提取、自行设置滤波器组的数目以及 mfcc 系数的数目,打印提取特征的维度,对提取的特征进行显示。
# # MFCC 特征
# 直接计算
if __name__ == "__main__":
file_wav = 'lsh2.wav'
y,fs = librosa.load(file_wav,sr=16000)
win_length =512
hop_length = 160
n_fft = 512
n_mels = 128
n_mfcc = 20
mfcc1 = librosa.feature.mfcc(y=y,
sr=fs,
n_mfcc=n_mfcc,
win_length = win_length,
hop_length =hop_length,
n_fft = n_fft,
n_mels = n_mels
)
print(mfcc1.shape)
# # 也可以提前计算好 log-power fbank特征来进行 mfcc的计算
fbank = librosa.feature.melspectrogram(y=y,
sr = fs,
n_fft = n_fft,
win_length = win_length,
hop_length= hop_length,
n_mels = n_mels)
print(fbank.shape)
fbank_db = librosa.power_to_db(fbank, ref=np.max)
mfcc2 = librosa.feature.mfcc(S = fbank_db,n_mfcc=20,sr = fs)
print(mfcc2.shape)
fig = plt.figure()
img = librosa.display.specshow(mfcc1, x_axis='time')
fig.colorbar(img)
plt.title("MFCC")
plt.show()
敬请期待接下来的更新
…………