聽歌識曲,顧名思義,用設(shè)備“聽”歌曲,然后它要告訴你這是首什么歌。而且十之八九它還得把這首歌給你播放出來。這樣的功能在QQ音樂等應(yīng)用上早就出現(xiàn)了。我們今天來自己動手做一個自己的聽歌識曲
我們設(shè)計的總體流程圖很簡單:
-----
錄音部分
-----
我們要想“聽”,就必須先有錄音的過程。在我們的實驗中,我們的曲庫也要用我們的錄音代碼來進行錄音,然后提取特征存進數(shù)據(jù)庫。我們用下面這樣的思路來錄音
# coding=utf8import waveimport pyaudioclass recode(): def recode(self, CHUNK=44100, FORMAT=pyaudio.paInt16, CHANNELS=2, RATE=44100, RECORD_SECONDS=200, WAVE_OUTPUT_FILENAME="record.wav"): ''' :param CHUNK: 緩沖區(qū)大小 :param FORMAT: 采樣大小 :param CHANNELS:通道數(shù) :param RATE:采樣率 :param RECORD_SECONDS:錄的時間 :param WAVE_OUTPUT_FILENAME:輸出文件路徑 :return: ''' p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(''.join(frames)) wf.close()if __name__ == '__main__': a = recode() a.recode(RECORD_SECONDS=30, WAVE_OUTPUT_FILENAME='record_pianai.wav')
我們錄完的歌曲是個什么形式?
如果只看一個聲道的話,他是一個一維數(shù)組,大概長成這個樣子
我們把他按照索引值為橫軸畫出來,就是我們常常看見的音頻的形式。
音頻處理部分
我們在這里要寫我們的核心代碼。關(guān)鍵的“如何識別歌曲”。想想我們?nèi)祟惾绾螀^(qū)分歌曲? 是靠想上面那樣的一維數(shù)組嗎?是靠歌曲的響度嗎?都不是。
我們是通過耳朵所聽到的特有的頻率組成的序列來記憶歌曲的,所以我們想要寫聽歌識曲的話,就得在音頻的頻率序列上做文章。
復(fù)習(xí)一下什么是傅里葉變換。博主的《信號與系統(tǒng)》的課上的挺水,不過在課上雖然沒有記下來具體的變換形式,但是感性的理解還是有的。
傅里葉變換的實質(zhì)就是把時域信號變換成了頻域信號。也就是原本X,Y軸分別是我們的數(shù)組下標(biāo)和數(shù)組元素,現(xiàn)在變成了頻率(這么說不準(zhǔn)確,但在這里這樣理解沒錯)和在這個頻率上的分量大小。
新聞熱點
疑難解答
圖片精選