簡體   English   中英

Python 中的帶通濾波器

[英]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')

下載文件Input.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...

下載 Output 文件

輸入文件是立體聲的。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM