[英]Pass_band filter in Python
我開發了一個腳本,它給定一個輸入文件,提取語音信號並在 output 中給出沒有語音的信號(因此包含噪聲的信號):
!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')
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 秒,而不是 output 為 1:12...
輸入文件是立體聲的。 pydub 文檔指出:
AudioSegment(…).get_array_of_samples() 將原始音頻數據作為(數字)樣本數組返回。 注意:如果音頻有多個通道,每個通道的樣本將被序列化——例如,立體聲音頻看起來像 [sample_1_L, sample_1_R, sample_2_L, sample_2_R, ...]
對於 scipy 這只是 1 個“長”通道。 它無法知道樣本是這樣拆分的。 過濾器也有 state。 這意味着它無法處理像這樣混洗的數據並產生所需的 output。
例如,您將 AudioSegment 中的數據重塑為 2 個 mono 通道,例如:
[sample1L, sample2L, ...]
和
[sample1R, sample2R, ...]
並單獨處理這些。
或者
您只需將 AudioSegment 轉換為 mono。 像這樣:
audio = AudioSegment.from_file('fileInput.mp3')
audio = audio.set_channels(1)
無論哪種方式,我都強烈建議您在需要采樣率的地方使用輸入文件的采樣率。 否則以其他采樣率加載文件將改變濾波器頻率並改變 output 文件的長度和播放速度。 例如
sos = signal.butter(10, [100, 4000], 'bandstop', fs=audio.frame_rate, output='sos')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.