背景需求
在處理音頻中,我們可能會有這樣的場景:隨著語音設備的能力越來越強,音頻數據越來越大。但實際上,音頻中的有效部分卻很少,抑或是音頻的背景聲過大,非目標聲音。在這樣的場景下,我們希望得到人聲,去掉噪聲,提高信噪比。
問題界定
這裡將問題進行界定,進行子任務拆分:
- 將音頻的背景聲音去除,
- 去除“無聲”階段。
解決方案
以保持最高的信噪比。這以需求在很多場景中有見:比如課堂錄音的提取,或者是錄音筆的數據存儲。
在使用本領域“高深”的技術前,一定要思考,切莫手上有錘子,就看啥都像釘子。想想該領域的專家會怎麼做,如何從專業角度看待該問題;其次想想普通人會怎麼做,防止落入經驗主義陷阱。
背景聲音的剝離,最簡單的其實是音軌分離。其前提是兩種聲音存為了不同的音軌,在一些場景很合適。比如電話錄音。
背景聲分離
但是若只有一個音軌呢?別擔心,機器學習來幫助你。spleeter 基於 tensorflow,訓練了一套音樂檢索系統,能夠有效的分離人聲和背景音樂聲。
該工具已經進行封裝,對於簡單的人聲分離,採用直接調取的方式即可。代碼如下
<code># Use audio loader explicitly for loading audio waveform :
from spleeter.audio.adapter import get_default_audio_adapter
audio_loader = get_default_audio_adapter()
sample_rate = 44100
waveform, _ = audio_loader.load('/path/to/audio/file', sample_rate=sample_rate)
# Perform the separation :
prediction = separator.separate(waveform)/<code>
空白切割
在分離之後,得到人聲和背景聲。人聲分離後,仔細聽,就會發現裡面有很多空白。對於空白部分,進行切割分離。
這裡參考 stackoverflow 的代碼
<code>from pydub import AudioSegment
from pydub.utils import db_to_float
# Let's load up the audio we need...
podcast = AudioSegment.from_mp3("podcast.mp3")
intro = AudioSegment.from_wav("intro.wav")
outro = AudioSegment.from_wav("outro.wav")
# Let's consider anything that is 30 decibels quieter than
# the average volume of the podcast to be silence
average_loudness = podcast.rms
silence_threshold = average_loudness * db_to_float(-30)
# filter out the silence
podcast_parts = (ms for ms in podcast if ms.rms > silence_threshold)
# combine all the chunks back together
podcast = reduce(lambda a, b: a + b, podcast_parts)
# add on the bumpers
podcast = intro + podcast + outro
# save the result
podcast.export("podcast_processed.mp3", format="mp3")/<code>
最後,得到完整的人聲部分。
其它參考
Noise reduction using spectral gating in python
Udacity 2018 Machine Learning Nanodegree Capstone project
閱讀更多 穀粒說數 的文章