scipy Python中的带通滤波器(_B)

mi7gmzs6  于 2022-11-10  发布在  Python
关注(0)|答案(1)|浏览(178)

我已经开发了一个脚本,给定一个输入文件,提取语音信号,并在输出信号没有语音(所以信号,包含噪音):

!pip install pydub
from pydub import AudioSegment
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
audio = AudioSegment.from_file('fileInput.mp3')

Download fileInput.mp3

samples = audio.get_array_of_samples()
plt.plot(list(samples))

from scipy import signal
sos = signal.butter(10, [100, 4000], 'bandstop', fs=44100, output='sos')

filtered = signal.sosfilt(sos, np.array(samples))

plt.figure(figsize=(10,10))
plt.plot(np.array(samples))
plt.plot(filtered)

plt.title('After 1 - 10 Hz pass-band filter')

plt.tight_layout()

plt.show()

要导出过滤后的文件(即包含噪声的文件),我将以下行写入:

from scipy.io.wavfile import write

write('./test.wav', 44100, filtered.astype(np.int16))

代码保存文件文件与原始(输入)文件的长度不同。

正如你可以注意到的,输入文件有36秒的长度,而不是输出是1:12 ...
Download Output file

jogvjijk

jogvjijk1#

输入文件是立体声的。pydub文档声明:
AudioSegment(...).get_array_of_samples()将原始音频数据以(数字)样本数组的形式返回。注意:如果音频有多个通道,则每个通道的样本将被串行化-例如,立体声音频将类似于[sample_1_L,sample_1_R,sample_2_L,sample_2_R,...]
对于scipy来说,这只是一个“长”通道。它不知道样本是这样分割的。滤波器也有状态。这意味着它不能处理像这样混洗的数据并产生所需的输出。
您可以将AudioSegment的数据重新整形为2个单声道,例如:

[sample1L, sample2L, ...]

[sample1R, sample2R, ...]

并分别处理这些数据。

您只需将音频段转换为单声道。如下所示:

audio = AudioSegment.from_file('fileInput.mp3')
audio = audio.set_channels(1)

无论哪种方式,我都强烈建议您使用输入文件的采样率,只要需要采样率。否则加载一个具有其他采样率的文件将改变滤波器频率,并更改输出文件的长度和播放速度。

sos = signal.butter(10, [100, 4000], 'bandstop', fs=audio.frame_rate, output='sos')

相关问题