使用譜減法對語音信號進行降噪(librosa)

基本思想是把時域信號轉換到頻域進行處理,處理完畢後再轉回時域信號,具體算法可以參考:

https://blog.csdn.net/godloveyuxu/article/details/69225790

 

使用C#對語音信號降噪處理比較困難,查閱資料知道可以使用Webrtc或者speex進行降噪,不過核心思想都是把C++轉成dll庫供C#調用,由於對C++不是很熟悉,折騰了好久都沒有實現,如果想了解一下,下面的文章可以參考一下:

Webrtc:https://www.cnblogs.com/Hard/p/csharp-use-webrtc-noisesuppression.html

speex::https://blog.csdn.net/u012931018/article/details/16927583

              https://www.cnblogs.com/zhuweisky/archive/2010/09/16/1827896.html

speex源碼:http://zxy15914507674.gitee.io/shared_resource_name/speex-1.2beta3-win32.zip

 

國內在多人語音聊天中,能使用C#進行二次開發的公司有傲瑞科技http://www.oraycn.com/Download_Free.aspx,但是要收錢

 

最後考慮使用python的librosa模塊實現,採用WCF和XML-RPC的方式進行調用(本文並沒有實現)

 

本文大部分內容轉自:https://blog.csdn.net/Boogyman/article/details/103264392

測試環境:

window server 2012

Anaconda

 

步驟:

下面代碼中的測試文件可以從這裏下載:http://zxy15914507674.gitee.io/shared_resource_name/librosa資源文件.rar

1 安裝librosa模塊,參考:https://blog.csdn.net/zzc15806/article/details/79603994

由於我使用的的Anaconda,所以使用命令

conda install -c conda-forge librosa

進行安裝

2  當報NoBackendError這樣的錯誤時,還需要安裝ffmpeg模塊,輸入下面的命令

conda install ffmpeg -c conda-forge

3   輸入代碼如下:

import numpy as np
import librosa
import scipy
from scipy import io


class SpecSub(object):

    def __init__(self, input_wav):

        self.data, self.fs = librosa.load(input_wav, sr=None, mono=True)
        self.noise_frame = 3  # 使用前三幀作爲噪聲估計
        self.frame_duration = 200/1000  # 200ms 幀長
        self.frame_length = np.int(self.fs * self.frame_duration)
        self.fft = 2048  # 2048點fft

    def main(self):
        noise_data = self.get_noise_data()

        oris = librosa.stft(self.data, n_fft=self.fft)  # Short-time Fourier transform,
        mag = np.abs(oris)  # get magnitude
        angle = np.angle(oris)  # get phase

        ns = librosa.stft(noise_data, n_fft=self.fft)
        mag_noise = np.abs(ns)
        mns = np.mean(mag_noise, axis=1)  # get mean

        sa = mag - mns.reshape((mns.shape[0], 1))  # reshape for broadcast to subtract
        sa0 = sa * np.exp(1.0j * angle)  # apply phase information
        y = librosa.istft(sa0)  # back to time domain signal

        scipy.io.wavfile.write('./output.wav', self.fs, (y * 32768).astype(np.int16))  # save signed 16-bit WAV format

    def get_noise_data(self):
        noise_data = self.data[0:self.frame_length]
        for i in range(1, self.noise_frame):
            noise_data = noise_data + self.data[i*self.frame_length:(i+1)*self.frame_length]
        noise_data = noise_data / self.noise_frame

        return noise_data


ss = SpecSub('./test.wav')
ss.main()
print('done')
    

輸出的效果還算不錯,但發現1M不到的音頻文件降噪後變成3M多的音頻文件,在實時語音聊天中,這明顯不符合要求,而且該模塊讀入的是待處理的音頻文件,而不是字節流,這意味着C#發送過來的音頻數據(字節數組形式的數組)只能還原爲音頻文件才能給python進行處理,這明顯是不行的,不知你有什麼好的辦法,請多多指教。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章