用python的librosa库和soundfile对一段音频进行短时能量与谱质心特征的端点检测并绘制端点检测和声音短时能量与谱质心的示意图,并通过检测到的端点信息对音频静音区进行辨别并绘图,再将音频进行去除静音操作并绘制去静音前后的端点检测对比图,再将去除静音后的音频保存在本地文件夹。
时间: 2023-06-24 13:05:31 浏览: 213
Acoustic-analysis:通过python进行声音和音乐分析
下面是代码实现:
```python
import librosa
import soundfile as sf
import numpy as np
import matplotlib.pyplot as plt
# 加载音频文件
audio_file = 'example.wav'
y, sr = librosa.load(audio_file, sr=None)
# 计算短时能量特征
frame_length = int(0.02 * sr)
energy = librosa.feature.rms(y, frame_length=frame_length, hop_length=frame_length, center=True)
# 计算谱质心特征
spec_cent = librosa.feature.spectral_centroid(y, sr=sr, n_fft=frame_length, hop_length=frame_length, freq=None)
# 绘制短时能量与谱质心特征
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(np.arange(len(y)) / sr, y)
plt.plot(np.arange(len(energy[0])) * frame_length / sr, energy[0], color='r')
plt.ylabel('Energy')
plt.subplot(2, 1, 2)
plt.plot(np.arange(len(y)) / sr, y)
plt.plot(np.arange(len(spec_cent[0])) * frame_length / sr, spec_cent[0], color='r')
plt.ylabel('Spectral Centroid')
plt.xlabel('Time (s)')
plt.show()
# 端点检测
threshold_energy = 0.1 # 短时能量阈值
threshold_spec_cent = 1000 # 谱质心阈值
endpoints = []
is_speech = False
for i in range(len(energy[0])):
if energy[0][i] > threshold_energy and spec_cent[0][i] > threshold_spec_cent:
if not is_speech:
endpoints.append(i * frame_length)
is_speech = True
else:
if is_speech:
endpoints.append(i * frame_length)
is_speech = False
if is_speech:
endpoints.append(len(y))
# 绘制端点检测结果与静音区域标记
plt.figure(figsize=(10, 6))
plt.plot(np.arange(len(y)) / sr, y)
for i in range(0, len(endpoints), 2):
plt.axvspan(endpoints[i] / sr, endpoints[i+1] / sr, color='r', alpha=0.2)
plt.xlabel('Time (s)')
plt.show()
# 去除静音
y_new = np.array([])
for i in range(0, len(endpoints), 2):
y_new = np.concatenate((y_new, y[endpoints[i]:endpoints[i+1]]))
sf.write('example_no_silence.wav', y_new, sr)
# 绘制去静音前后的端点检测对比图
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(np.arange(len(y)) / sr, y)
for i in range(0, len(endpoints), 2):
plt.axvspan(endpoints[i] / sr, endpoints[i+1] / sr, color='r', alpha=0.2)
plt.xlabel('Time (s)')
plt.title('Before Removing Silence')
plt.subplot(2, 1, 2)
plt.plot(np.arange(len(y_new)) / sr, y_new)
plt.xlabel('Time (s)')
plt.title('After Removing Silence')
plt.show()
```
上述代码中,我们首先使用 `librosa.load` 函数加载音频文件,并计算出短时能量和谱质心特征。然后,我们绘制出短时能量和谱质心特征的示意图。
接着,我们使用一个简单的算法进行端点检测。具体来说,当短时能量和谱质心同时超过一定阈值时,我们认为这是语音信号,否则就是静音区域。我们将检测到的端点信息保存在 `endpoints` 列表中,并绘制出端点检测结果和静音区域标记的示意图。
然后,我们使用 `numpy.concatenate` 函数将去除静音后的音频片段拼接起来,并使用 `soundfile.write` 函数将音频保存在本地文件夹中。最后,我们绘制出去静音前后的端点检测对比图。
需要注意的是,上述代码中的阈值和算法只是一个示例,实际应用中需要根据具体情况进行调整和优化。
阅读全文