# 自動化生成音樂譜 > [AUTORHYTHM: A MUSIC GAME WITH AUTOMATIC HIT-TIME GENERATION AND PERCUSSION IDENTIFICATION](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=7177487) ```graphviz digraph G { node [shape = box, style=rounded] src [label="wav_file", shape = plain] sep [label="sound separation"] det [label="onset detection"] det2 [label="onset detection"] comb [label="result combination"] near [label="Nearby onsets removal"] grouping result [label="Result\ntime | col_id | difficulty"] src -> sep -> det -> comb -> near -> grouping -> result sep -> det2 -> comb } ``` ## sound separation > [Harmonic–Percussive Separation (HPS)](https://www.audiolabs-erlangen.de/resources/MIR/FMP/C8/C8S1_HPS.html) > [Numpy 版本教學](https://medium.com/@ongzhixuan/exploring-the-short-time-fourier-transform-analyzing-time-varying-audio-signals-98157d1b9a12) 論文使用 Harmony/Percussive Source Separation (HPSS) 作為分離和諧音以及打擊音的手段 <img src="https://hackmd.io/_uploads/ByDeO9FmR.png" width=500> 音樂可分為和諧音 (harmonic sound) 與打擊音 (percussive) 和諧音聽起來就是和弦,如小提琴的琴聲,頻譜上對應到正弦波 (sinusoid),在聲譜圖 (spectrogram) 上對應的形狀為一橫線 打擊音聽起來有如衝擊般,可以理解為聲樂上的衝擊,聲譜圖上對應形狀為一直線 輸入訊號經過時頻分析 (利用短時距傅立葉轉換,STFT),可以得到一段時間內頻率分布變化圖 所謂的 STFT,其實就是一個函數乘上在固定時間不為零的窗函數 (window function,可用 `np.hamming` 實現),再進行一維的 FFT (可用 `np.fft.rfft` 實現) 現在有了時頻譜,要怎麼分離和諧音跟擊打音呢? 如果使用橫向濾波器,就能得到頻譜多為橫向的和諧音了 為了做到這個,我們使用中位數濾波器 (median filter) 求出過濾後的時頻譜後,我們不會直接使用其結果,而是用橫向直向的時頻譜構造出軟遮罩 (soft mask) 根據求得的橫向訊號成分 $y_h(n,k)$ 以及縱向 $y_p(n,k)$ 可以設計以下遮罩: $$ M_h(n,k)=\frac{y_h(n,k)+\epsilon/2}{y_h(n,k)+y_p(n,k)+\epsilon} $$ $M_p(n,k)$ 同理,更換分子就行 注意到我們討論到以下參數: - N: 視窗長度 - H: hop length - l_p, l_p: filter length 強度頻譜 (magnitude spectrum) <img src="https://hackmd.io/_uploads/rJYjw8_QC.png" width=300> 根據觀察,不同擊打音效在不同的頻率上,各會有不同的峰值和波形 論文定義「突出音」為具有前 15% 強度的頻率區間 <img src="https://hackmd.io/_uploads/Sk7BF8OXR.png" width=300> onset detection: spectral-flux-based onset detection 輸出型態: 發生時間 | 欄位的 id | 困難度 偵測到人聲/打擊的發生次數,合併起來就是最終結果 ## onset detection 為了減低背景音樂干擾,每一 frame 的強度頻譜都減去了其平均值,所以結果的frame magnitude 總和都是 0 論文中的 threshold 是源於使用者自行輸入的音檔 找出使用者給定的每種音效 (percussion sound) 突出音後,計算每一幀突出音的平均力度規模 (power magnitude) 另外,根據世界紀錄,連續兩個打擊音最小間隔約為 71.4 ms ## channel assignment > [MFCC intro](https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html) > [DCT 介紹與應用](https://medium.com/%E9%9B%BB%E8%85%A6%E8%A6%96%E8%A6%BA/%E9%9B%A2%E6%95%A3%E9%A4%98%E5%BC%A6%E8%BD%89%E6%8F%9B-discrete-cosine-transform-dct-%E7%B0%A1%E4%BB%8B-65e426018264) 為了將不同樂器的打擊音分配給不同音軌,對於 MFCC (Mel-frequency cepstral coefficient) 使用 k-means clustering 在過往文獻中, MFCC 被用來做為表示「音色」的特徵 從音訊擷取 MFCC 的過程如下圖,首先經過 FFT 獲取取 log 的功率頻譜 (power spectrum),並經由重新取樣為梅爾刻度 (mel scale) 後,再經由離散餘弦轉換 (discrete cosine transform, DCT,只涉及實部運算) <img src="https://hackmd.io/_uploads/BkV1m42QC.png" width=500> 於是經由這兩種頻譜上的轉換後,可以得到 「頻譜的頻譜」(spectrum of spectrum) 可以回想自我相關函數 (autocorrelation),其作用為量化自身訊號,和不同時間差相較起來的相似程度。MFCC, 或者說 `DCT(abs(FT))` 與自我相關函數不同的是,前者較不易受基頻 (fundamental frequency) 移除的影響。當帶通濾波器 (bandpass filter) 用以過濾訊號時,就會有些基頻被移除 總的來說,MFCC 用來量化高頻訊號 (high-pass filtered signal) 的自我相似程度 一個前處理技巧是前強化 (pre-emphasis) 藉以加強高頻訊號的強度。通常高頻會比低頻的強度小,也可以改進 SNR,更能避免做 FFT 產生的數值問題 我們在音頻處理會傾向使用梅爾刻度 (Mel-scale) 取代赫茲,是為了模仿人耳非線性接收音頻的特性 $$ m=2595\log_{10}(1+\frac{f}{700}) $$ 獲得時頻譜 (spectrogram) 後,會發現其中的濾波器組常數 (filter bank coefficient) 呈現高度相關,因此我們會對其進行離散餘弦轉換 (DCT),得到經壓縮的表示 轉換後的結果就是所謂的 MFCC 最後將 sinusoidal liftering 作用於 MFCC: $\hat{MFCC_i}=w_iMFCC_i$ $$ w_i=1+\frac{D}{2}\sin(\frac{\pi i}{D}) $$ 論文認為,這個濾波函數可以改進噪音之下,聲音辨識的能力。其給予較高常數更小的權重