2011年2月18日 星期五

HMM with HTK, HTS system - 仕偉

--------Synthesis Results-------

Star Variations

1. Song1
2. Song2
3. Song3
4. Song4
5. Song5
6. Song6
7. Song7
8. Song8
9. Song9
10.Song10

-------- 2011 . 2. 18之2---------

對於F0基頻設定,trace code結果後發現:

1. 445Hz要設定LOWERF0=200,UPPERF0=600,基頻的值才會正確被找到。(正確)

2. 如果設定LOWERF0=100,UPPERF0=500,基頻值會找到2百多Hz。(錯誤)

-------- 2011 . 2. 18 ------------

目前在training音檔時發現幾個問題:

1. 如果我們設定每個state要分成N個HMM model的話,那麼這個state的長度就要大於等於N*0.01(秒),最小的duration要設為N。

在HTS中每個state並不是只有一個HMM model去training,而是拆成N個HMM model,而N的大小可以設定。

之前training設的N值是5,也就是每個state長度至少要大於0.05(秒)。

我們可以設定N為3,所以在跑matlab程式時,設定state的最小長度至少要0.03(s),最好的長度是多少還要再實驗。

2. 在分state的演算法中,之前我有加入一個條件,就是找出頻率轉折點;實際跑時遇到一個例子,頻率是[ 444.75, 444.79, 444.81, 444.80, 444.78, 444.77],這段頻率人耳聽起來是沒有差異,但是依照演算法會被分成[ 444.75, 444.79, 444.81 ] , [ 444.81, 444.80, 444.78, 444.77 ]兩段,在training時應歸為同一類。此部分已修改完。

3. 再取F0部分用HTS範例的取F0程式會有問題,例如基頻是445Hz,在取F0時設定最低400Hz,最高500Hz的話會找不到基頻,猜想因為是語音所以設定的頻率較低,目前在trace code看他取基頻的程式是如何。

附上有做好的進度,紅色為未完成。
基頻目前是直接用讀程式的值,以後應該要人工修一下;還有產生state sequence的程式還沒寫好。



-------- 2010 . 12. 28 ----------

Speech Parameter Generation Algorithm
Considering Global Variance for
HMM-Based Speech Synthesis




-------- 2010 . 12. 9 ----------

我在網路上有找到已經有人用matlab來讀
htk的參數的例子,並且他也用自己的方法算出
MFCCs與htk的MFCCs作比較,如圖:



input是htk的MFCCs檔案跟原音的wave檔.

網址:http://labrosa.ee.columbia.edu/matlab/rastamat/mfccs.html


-------- 2010 . 12. 8 ----------

AN ALGORITHM FOR SPEECH PARAMETER
GENERATION FROM CONTINUOUS MIXTURE
HMMS WITH DYNAMIC FEATURES



-------- 2010 . 12. 2 ----------

上次音檔vibrato不像的原因是因為model分類沒分好,
也就是decision tree未建好.

正常來講,依前後state不同,同一state的model也應該要分類.
例如attack + vibrato_rise 跟 vibrato_fall + vibrato_rise,
兩個vibrato_rise應該要有不同的model,之前合成是只有一個model.

改進之後將上述情形分成不同的model,最後合成結果:

gen1
gen2,延長vibrato
gen3,用不同的vibrato state去合成

目前進度:用matlab將mfcc參數取出,之後要做clustering.

-------- 2010 . 11. 21 ----------

延續11月19日,新增合成音檔,
vitrato的rise和fall的state重複多遍, sample rate 44100Hz :

Synthesis D4 Vibrato2 44.1KHz

-------- 2010 . 11. 19 ----------

修改了sample rate為44100Hz,
training完後8000Hz以上頻率有找到,聽起來又更像了.

但比較有趣的是,同樣都用hts_engine但產生的音檔聽起來不一樣,應該是少打參數.

因為我得到合成的音檔有兩種方式:

1. 依照script,training完會自動執行hts_engine幫我產生音檔.

2. training完我手動將產生的model參數移到另一個資料夾,自己下指令用hts_engine合成音檔.
可能是我手動下指令少了什麼參數,所以跟自動產生的音檔不像,這點有待查明.

原音D4

1.Synthesis D4 sample rate 44.1KHz

2.可能少打參數 D4 sample rate 44.1KHz


-------- 2010 . 11. 11 ----------

問了奕欽學長關於training model時基頻有沒有限制範圍,
有!!他說有而且可以修改範圍,
找到data/Makefile內有兩行:
LOWERF0 = 110 # lower limit for f0 extraction (Hz)
UPPERF0 = 280 # upper limit for f0 extraction (Hz)
就是萃取f0時設的範圍.

所以之前音檔會有低頻雜音可能是因為
原本的聲音的基頻是300Hz,
造成程式在training時硬要是找110~280內的頻率當基頻,
所以才會有低頻的雜音.

先來實驗看看改範圍能不能解決這個問題!

//////////////////////////////////////

將範圍改成 200~500 Hz
LOWERF0 = 200 # lower limit for f0 extraction (Hz)
UPPERF0 = 500 # upper limit for f0 extraction (Hz)
雜音的問題就解決了.

//////////////////////////////////////

接著實驗vibrato :

原音D4 295Hz Vibrato

將同一音檔copy 10份去training, 並且合成 :

Synthesis D4 295Hz Vibrato1

又將vitrato的rise和fall的state重複多遍 :

Synthesis D4 295Hz Vibrato2

以上為目前結果.

-------- 2010 . 11. 08 ----------

這禮拜利用小聽給的java讀cue的程式,
寫了個GUI介面,並修改成HTK label檔的格式如下圖:

只要用程式開啟標完cue的wave檔,就可顯示cue內容,
按下save to label就可存成label檔.

此外程式也提供一般的txt格式,輸出單位為秒如下圖:

一樣只要按下save to txt就可存成txt檔.


這禮拜即利用此程式去標出上次合成出來有雜音問題的D4
(上次報告是說G1,去看頻譜才發現說錯了是D4才對),
合成出來仍有低頻的雜音參雜其中.

目前解決的辦法就是先去拆解hts_engine程式看它產生音檔的部分,
順便拆解流程.



-------- 2010 . 11. 02 ----------

Cepstral Analysis Synthesis on the Mel Frequency Scale



-------- 2010 . 10 . 25 ----------

經過修改與測試之後原來是question set的問題.
目前已有合出聲音,聽得出來像是小提琴的聲音.

下一步是用cool editor邊看頻譜邊標音,這樣可以標得比較準確,
並把其他不同的state也加入training.


-------- 2010 . 10 . 13 ----------

目前有成功產生音檔,但聽起來不像violin的聲音.

可能有問題的點是:
1. 在標音的時候就沒有標好.
2. question沒建好,問題太少.
3. state間的關係描述太少,例如語音中有分片語,短語,音節,重音等,會用這些關係建HMM model.但我在實驗中只用到音節的關係.

目前先嘗試:
用同一個音檔重複10次,然後去training,再合成出來,看出來的音是不是跟原來的一樣.


-------- 2010 . 10 . 3 -----------

6.
對HMM model作初始化用HInit和HRest,
trace code發現是指令下錯的關係.
先用HInit對要處理的phone的HMM model作uniformly segmented,
再來用HRest對同一個HMM model作Baum-Welch re-estimated.
如此反覆將所有的phone都執行上述兩個指令後,
HMM model的初始化完成.


7.
依HTK格式將所有初始化好的HMM model集合成同一個檔案:
inic.mac

8.
開始HMM training:
用HERest這個指令也是會跑Baum-Welch re-estimated,與HRest不同之處是HRest只對單一個utterence做處理,HERest在training過程則是處理全部的utterence,並統計每個utterence的means,variances等,用於完善HMM參數.
處理完得到每個phone訓練好的HMM model.

9.
有了HMM model接下來是合成部份,用的是另一個系統:HTS.
合成需要的參數要有decision tree, question set,這部份如何產生我還要再去研究and問學長,目前進度到此.


-------- 2010 . 9 . 30 ----------

1.
從小提琴的音檔分出C1,G1,D2,A2四個音,每個音準備的音檔數目如下:
C1 : 7個音檔 - 1-1.wav ~ 1-7.wav
G1 : 7個音檔 - 2-1.wav ~ 2-7.wav
D2 : 7個音檔 - 3-1.wav ~ 3-7.wav
A2 : 6個音檔 - 4-1.wav ~ 4-6.wav

2.
接下來取spectrum參數,先用語音預設的39維Mel-frequency cepstral coefficients.
由於HTK只吃16bit或8bit的wave format,因此先用cool editor將wave檔降碼.
取完可得*.fea檔案.

3.
接著是人工標音,使用HTK提供的工具,指令打"HSLab -F WAVE"才能讀入wave檔,
標音的畫面如下:



目前HMM state暫定為"音階_ADSR_status",
example: "c1_A"代表音色為c1,狀態是attack,其他命名以此類推.
將所有的音檔標示完會有相對應的*.lab檔.

4.
依HTK格式將所有lab檔案集合成1個*.mlf檔.

5.
產生HMM model的template,
指令"outMacro Plainhs DiagC 3 "1 1 1" MFCC_E_D_A "13 13 13" > template.hmm",
意思是每個model有三個state,每個state有三個stream,分別用1個、1個、1個mixture,每個stream各佔13維度。

6.
接著對HMM model作初始化用HInit和HRest,
目前這邊有錯誤,下HInit指令時會有
"ERROR [+2121] HInit: Too Few Observation Sequences [0]",
錯誤可能發生的原因有幾種:
1.樣本數太少.
2.HMM model template設的不對,無法跟*.fea檔相符.
3.取segment時人工切的frame間隔太小,導致取不到參數.

解決辦法:
問學長and直接trace code找error.

-------- 2010 . 8 . 12 ----------

執行HTS的demo檔案,網頁上有分兩種 :
Speaker dependent training demo : training 單獨一人的HMM model.
Speaker adaptation/adaptive training demo : training 不同人的HMM model; 例如要讓speaker A發出的語調要像speaker B, 或是speaker A發出的語調像speaker B+C+D.

每種語言又分兩種demo :
Normal demo : HTS 內建的方法取 spectral parameter.
STRAIGHT demo : 由另外一位學者自行改進的演算法取 spectral parameter.由於STRAIGHT demo的方法並沒有公開程式碼,需要的話要自行跟那位教授聯絡取得,因此一般都是執行Normal demo.

我跑的是Speaker dependent training demo : English : Normal,如圖紅框所示 :


跑完成約需要6~7個小時,會有HMM model的統計資料,包含f0,spectral等,之後就可以直接用這些資料透過hts_engine直接合成聲音.

目前已跑完取得統計資料,正在研究hts_engine如何使用.

參考網頁 : http://hts.sp.nitech.ac.jp/?Download

-------- 2010 . 8 . 3 ----------

HMM-based speech synthesis system(HTS)



介紹如何從音檔轉成參數再來合成語音.

-------- 2010 . 8 . 1 ----------
About HTS and HTK system.

HTK - Hidden Markov Model Toolkit
HTS - HMM-Based Speech Synthesis System

語音合成分為兩部份:training part 和 synthesis part
其中HTK就是負責training參數,HTS則是負責synthesis.

HTS內沒有加入text analyzer,如果要使用要另外下載,
Festival Speech Synthesis System就是個text analyzer.

HTS有內建hts_engine可以在不需要HTK library的情形下單獨執行,
可配合Festival或其他應用程式使用.

HTS是以patch檔的形式存在,安裝後會對HTK及HDecode作更新.
因此除了HTK外還需先裝好HDecode.

-------- 2010 . 7 . 8 ----------

viterbi algorithm

介紹如何將最小單位發音,切成我們指定的HMM state數目.


-------- 2010 . 7 . 7 ----------


接下來要做的就是去看合成的部分,

並將裡面取特徵參數的方法MFCC改為簡單的LPC,

再去合成看看看有沒有什麼問題。

下圖為HTK內建取特徵參數的方法,共有7種類型:



-------- ------------- ----------

2011年1月13日 星期四

沒有你們,生命就不精采:我的懺悔文

從1994年回國開始在交大兼任開始算起,我在研究與教學的位置上已經17年了。一剛開始還只是玩票性質,但是當隔年決定到中華大學任教時,對於如何當一個好老師這件事成了我第一件與最重要的思考要件,多年來沒有改變過。



但是以做一個研究人員來說,我不覺得自己是成功的。以目前學術界的氣氛,發表足夠多的質量的論文是評斷一個研究者最直接與簡單的方法。就這一點來說,我不算是個好的研究人員,因為我的被訓練過程裡,寫論文從來不是最重要的,也看多不太有用的論文,大概也因為這樣子,我不太愛寫論文,而喜歡做一些自己覺得有趣與有用的論文。在美國,我接收到的觀念是:能拿到Funding的研究才算是有用的研究,尤其像是史丹福這種學校。問題是並非所有研究都可以拿到Funding,所以出論文也是一個不算太差的評斷標準,只不過我的偏見讓我覺得要是寫些自己都不確定會不會有用的論文,那還不如做一些有趣的應用還好些。

也因為如此,我的論文很少。而就我自己的標準來說,質也不好。因為每當一篇論文寫好,或甚至登出來之後,我就開始覺得自己做得不好。這樣子的心理,讓寫論文變成一件難過的事。但是,這樣子下去,對於學生的畢業會有問題,所以我總是勉力做下去,論文雖不多,但是夠學生畢業就好。這幾年政府五年五百億的政策,讓論文發表一事更形複雜,缺少論文,不僅個人升等,學生畢業受拖累,其影響層面更是深遠,我就不再這裡多說,一剛開始,我還是堅持要好的研究才寫論文,但是,大勢所趨,我不能因為自己不在乎升等這件事而影響學生的前途,我想自己還是放棄一些堅持,畢竟,一篇論文只需要三到四位審查委員的同意即可。

但是,可想而知,我寫論文的取向,選擇容易出論文的題目,投稿的技巧,甚至決定怎麼運做實驗室來讓出論文變成簡單一點,等等,都不太純熟。當有學生跟我提起我的實驗室的論文極少時,我也只能不好意思的承認了。

不再有論文壓力的我只能說,為了學生著想,只好老狗學新把戲一樣來面對這日益複雜的論文大環境。

我跟自己說:繼續努力。

多年來,在這個工作崗位上我卻有另一個讓我自己覺得驕傲的地方。那是教學方面的。上課方面盡力之外,最重要的是帶學生做研究。

每一個學生我都盡力去了解他們的個性,把他們當做家人,當做子弟來看待。每個星期的一對一或一對二的Meeting,甚至還幫學生看code或寫幾行sample code給他們參考,這樣子讓我可以更了解每一個學生的特質,也因此可以隨時調整我帶他們的方法與態度,只要兩年下來,功夫都會有長進,若是博士班的學生,雖說不一定很會寫論文,但是實做與研究能力都會變得很好。於是,每一天我都拖著極度疲累的身心回家,但是,也無形中跟學生的感情就很好,畢業後,我當他們是朋友,,而多數學生畢業後都跟我保持聯絡,也還會回來看我,有男女朋友也會跟我說或帶來給我看看,結婚都會請我去吃喜酒,甚至還會在我生日時回來幫我過生日。

不過,這一切從2006年我接任計網中心的行政職務開始變了。我把許多時間投入在改善學校行政電腦化的工作,雖然三年下來,做了非常多改善,可是畢竟一個人一天只有24小時,加上Diane到來,我取消了每周一對一的師生討論,只以每周的Group Meeting取代,除非問題一看起來就很大,否則有何研究的問題只在那時討論,剛開始還感覺不到壞處,因為那時的研究生在大學部時就修過我的課,而過去我其實也花很多時間在大學部學生的輔導方面,所以跟大學部學生的感情也好。但是,越到後來,問題越多,我感到跟碩士班學生間的嚴重隔閡,所有學生的進展也慢了下來,然後,開始有學生兩年畢不了業,博士班學生到外面interm後不打算再回來繼續學業,這個實驗室出了毛病,而毛病的根源在我自己。

然後,我從同學眼中不再看到早期的學生看著我時的親近的眼神,我一向引以為傲的部分現在反而成為我最大的失落,但是病弱的身體讓我有藉口,直到,我自己的專題生,曾經是本系大學部前幾名的學生無法準時畢業,我覺得難過極了。諷刺的是,我竟然得到一個名不符實的優良教師獎,讓我連領獎都不敢去。

11月初,我的一位學生回到實驗室,決定完成學業。有一次,她跟我說她很不習慣現在的實驗室,因為一點discipline也沒有,老師不再跟過去一樣跟學生那麼親近,實驗室的研究能量嚴重下降,她跟我說,要不是當年我陪過她走過一大段做學問的路,今天她根本不會回來這樣子的地方。

對我來說,這是無比沉重的一席話,我誠意的接受下來,覺得慚愧,也願意懺悔。

我記得很久以前我說過一句話,現在我對自己再說一遍:

老師教給學生知識,學生拯救老師的靈魂。

對我來說,真的是我的學生在最重要的時刻拯救了我。

11月,我決心恢復一對一或一對二的師生meeting,不管我的身體有多麼疲累。雖然我的程式能力不再優良,但是眼光還沒退化殆盡,我陪著大家看Code,依照結果,當場請學生改code,一再的修正,一邊講解原因,一邊回到過去依照學生的特質來引導他們的教學方式。

老師用多少心思在學生身上,學生就會如實回應,真是一點不假。

12月,我把碩三的那位其實是極優秀的學生找回來,每周跟他做密集的討論,在12月的最後一星期,我讓他住到我家來,多次改進code,一邊幫忙看論文與彩排,終於在2010年12月的最後第二天完成口試。

兩個多月來,我懷著贖罪的心情努力著,我把實驗室的重點研究分成兩部分,一是以音樂為主,一是以系統實做為主,前者以做出一流的研究與論文為主,後者以架構多核心雲端基礎結構與應用為主,以做出有商業價值但不一定要出論文為目標。然後刪除其他能做想做但是不一定有資源與時間做的研究。

2011年1月,在音樂方面,我們終於有相當大的進展,這星期,我在會議時感謝我的學生容忍我這個怠惰已久的老師,感謝他們做出這麼棒的研究,讓我們在專精的這部分能夠有領先全球的研究機構的可能性,讓我可以不會愧對我的老師當年對我的教誨。在多核心系統方面,我們的軟硬體環境日益成熟,今年內,我們的以ARM與FPGA為元件的多核心系統以及我們稱為ThinCloud的雲端Infrastructure的原型將會問世。另外,有關SystemC運算核心的平行化也快要到開花的階段,而由玉琳獨自闖入的幼兒腦波研究領域也將會有第一份入門的研究成果產出,我衷心期盼因為她的努力可以為不幸的孩子帶來一點希望。

曾經,我以身為老師為終身志業,曾經,我一度迷失在這條路上,但是我覺得我的身上一定帶著眾多前世以來就一直帶在身上的地圖,所以我總是會找到回來的路,我想,至少在這一世我大概是不會再迷路了。

我再次對過去我所對不住的所有學生說抱歉,雖然人生無法重來,我也很難彌補我的過失,但是,我還是要厚顏的請求您們的原諒,同時也原諒我不時的疏忽,任性,甚至孩子氣等等種種缺點。假如在未來,你們需要我的意見的話,又或,您只是希望跟人話話家常,請隨時來找我,我總是我的辦公室裡或是家裡,放著音樂,準備好咖啡與茶在等帶著你們回來,希望能做你們一生中最好的朋友。

只是為了自己的生活而做事,這樣子的生命沒有意義。作為一個老師,沒有了能跟他成為終生朋友的學生,這樣子的生命就不精采。

某齣日劇裡,女主角問男主角覺得甚麼時候最幸福,男主角在劇中開了一間小小的花店,他回答道,當人家稱呼我為"花店老闆"時是我覺得最幸福的時候。

對我來說,那就是把"花店老闆"換成"老師"。我想現在的我是幸福的,希望你們也都能幸福。

2010系統層級程式設計簡介與實做

2011/1/12

期末Project評分方式請見:

期末作業評分

-------------------------------------------------

2010/1/5

期末Project:

期末作業的規範如下:

1. 使用8051當做中央處理的機器,此為模組一,其工作如下:

      1.1 接收來自影像輸入模組的資料。

      1.2 傳送已處理之影像資料至檔案寫入模組。

      1.3 接收來自參數模組織參數決定處理方式,處理動作於接收來自參數模組之訊息後才開始。

              1.3.1 如參數為0, 將每一影像pixel亮度加上20

              1.3.2 如參數為1, 將每一影像pixel亮度加上20

              1.3.3 如參數為2, 將每一影像pixel亮度取sqrt後乘以16

              1.3.4 如參數為3, 將每一影像pixel亮度平方後除以256

      1.4 通知影像輸入模組可以再輸入下一張影像

2. 影像輸入模組,此為模組二,其工作如下:

     2.1 主動輸入一張以YUV格式的影像,檔名由使用者輸入。

     2.2  顯示此一影像

     2.3  通知模組一來接收影像。

     2.4  接收模組一的訊息以示可以處理下一張影像。

3. 檔案寫入模組,此為模組三,其工作如下:

      3.1 接收來自8051處理後的影像資料。

      3.2 根據使用者輸入之檔名寫檔。

      3.3 顯示接收之影像

4. 參數模組,此為模組四,其工作如下:

     4.1 使用者輸入處理參數

      4.2 通知模組一接收參數並開始處理。

在此,不限定模組織間的溝通通道之實作方式,但是,如果以

1. 一個統一的匯流排(Bus)的方式實做(也就是另外設計Bus為模組五),加學期總分三分。

2. 如果定出Bus 的協定(含Timing Diagram)並實做出Cycle Accurate (CA)的Bus模組,再加學期總分五分。

以上加分機制實施後,以總分為99分為成績上現。

期末作業需含完整報告,並附執行檔,將視報告完整度酌量增加評分。如果只有程式以及可執行之執行檔,將只有期末作業50%的分數。

   期末Project期限為11:59:59PM, 1/24, 2011,不再展延。如之前有作業要補交,也請以之為期限,但成績以乘以0.7計。成績將於11:59:59AM, 1/26, 2011公佈在系辦公室公布欄,如有疑義,請在4PM, 1/26, 2011前向助教詢問是否有登記錯誤,之後將不再接受更改。

-------------------------------------------

2010/12/20

這是SystemC有關Ports的部分.

請在這裡下載: Ports

有關SystemC Communication的更詳細解說請見: SystemCBook

---------------------------------------------

2010/12/17

有關8051的簡介以及工具

請在這裡下載: SCREAM 805,  its toolchain and FPGA Emulator

----------------------------------------------

2010/12/15

豪文學長說上星期竟然沒有人把8051 Simulator灌起來,所以實在不知道大家的問題是什麼,請大家趕快動作,因為這個作業最困難之處在於環境的設定。程式倒還是其次。

以下是作業要完成的。

1. 使用 8051 ESL/SystemC Simulator,請先在上面跑一個簡單的程式,然後使用GDB來debug。簡易程式如下:

    main(){

         int i,k,j;

         k=1000;

         j=1000;

         for(i=0:i<k;i++) j- -;

    }

   請觀察j的值是否對了。請注意,要知道j有沒有算對,除了用GDB之外,還可以有什麼方法呢?

2. 使用學長提供的8051環境。學長已經提供了一個範例,那是用一個8051以外的Module與8051之間進行溝通。 請改寫此一範例,將上述程式的迴圈數改變。也就是k的內含值。此一外掛模組的功能是自鍵盤輸入一整數,再將此一數字傳到8051模組已更改回圈數。

3. 請增加一個模組,將8051計算的每一個j的值傳過去,然後寫入一個檔案。

4. 更改8051之程式,讓它可以接受多次的外部回圈數的設定,並保持第3部分之寫檔功能,直到輸入迴圈數為-1為止。

-----------------------------------------------

2010/12/8

這是SystemC有關Channels的討論與作法

請在這裡下載: Channels

------------------------------------------------



2010/11/17

這是SystemC有關Concurrency的討論與作法.

請在這裡下載: Concurrency

------------------------------------------------

2010/11/16

這是SystemC有關SC_THREAD與AC_METHOD大致的實作方式與範例.

請在這裡下載: Thread and Method

2010/11/3

這是SystemC有關Main Function以及Module Function的宣告以及大致的實作方式與範例.

請在這裡下載: Structure: Main and Module

----------------------------------------------------------

2010/11/3

這是有關解釋SystemC如何根據時序(Timing)來進行模擬, 因為所有硬體系統都需要跟時序相關的.

請在這裡下載: Timing

-------------------------------------------------------------------

2010/11/3

這是有關解釋SystemC的資料型態.

請在這裡下載: Data Types

_____________________________________________________

2010/10/21

這次的投影片是講解更多的範例以便讓同學多了解SystemC的寫法,這個投影片也是一般SCREAM Lab的自己內部訓練用的簡易型資料,在此同時也規定了第二次的作業。



請在此下載: System Beginners

------------------------------------------------

2010/10/19

對不起,借一下版面,今年的專題指導名單為:

1. 李柏毅

2. 陳政澤

3. 陳奇鴻

4. 林俊緯

假如前面四位有人改變心意的話,那麼

5. 柯旻漢

對不起,耽擱大家。並向沒抽到的說聲抱歉。

-------------------------------------------------

2010/10/11

這上星期,我們對ESL的重要性做了一點簡單的介紹,為了讓課程的主要進度可以快一點,所以我要先介紹一點SystemC,此一目前的ESL標準程式語言,等大家做了第一個SystemC作業後,再回頭來講ESL的其他觀念。

以下是SystemC的Overview: SystemC Overview

HelloWorld程式範例如下: SystemC HelloWorld Example

範例程式請在這裡下載: SystemC Overview Program Example

-------------------------------------------------

2010/10/6

作業上傳位址:

ip : 140.116.82.184
port : 21
user:eslcourse
password: scream

--------------------------------------------------

2010/10/5

這學期,我把上課順序調整一下,先講一點ESL的觀念,然後上SystemC的入門,再回來講完ESL。然後再上其他的課程。

這樣做的用意是8051在其他課程已經再上了,我等一下子再上,其用意只是在於補充一點資料以及我的實驗室所在用的 與8051有關的ESL工具。這是有關ESL的整體的概念性簡介:

Basics of ESL Design and Modeling

第二回上課投影片在此下載: ESL Basics

未來的Topics包含:

SystemC coding and simulation

Review of Verilog coding and simulation

SCREAM8051 and its Toolchain

OpenESL

Heterogeneous Simulation Environment

Simple SoC Design, Modeling and Simulation

HW and Grading: 五個, 分別練習 C++/Threads, 8051 coding, Verilog coding, SystemC coding

Term project: Simple SoC Modeling and Simulation Using 8051/ModelSim/SystemC/Verilog

HW(60%)+Project(40%). 如期末作業未交或兩個作業(或以上)未交則不及格. 作業必須要能正常執行, 否則視同未交.

課程資料:

主要上課資料: 線上投影片(PDF  格式)

參考資料: 1. SCREAM Lab Blog

               2. SCREAM Lab Open Source Blog

               3. SystemC From the Ground

               4. The Guide to SystemC

助教的Email: ProdigyJerry@gmail.com

假如你們還對此一topic想有進一步的了解, 可以Google以下的關鍵字。

1. SystemC Simulation Kernel

2. Advanced OpenESL tool development

3. TLM2.X

4. ARM Processor ESL Model

5. Multi-core Virtual Model

6. Multi-core Programming on Virtual Model

7. Multi-core application programming using CUDA

8. Debugging tool for microprocessors

 

---------------------------------------------------

我一直覺得SoC設計應該要由資訊系的學生來做才恰當, 但是資訊系的學生一向怕硬體, 為了破除這個問題, 我在2009的下學期的大學部開一門選修課, 課名如標題. 英文標題是:

Introduction to Programming and Tools of Electronic System Level (ESL) Design

我寫了第一階段的投影片, 用意在簡介一下ESL的設計觀念. 如下:

Electronic System Level Design Basics

上面投影片的內容還會再更新,但是可以供大家參考。

因為是大學部的課, 一些基本的東西還是要含蓋一下, 我又不想把課弄得講太多ESL, 可是實務卻做的少. 所以我計劃有一章是基本工具與知識的介紹, 以便在實做term project或Homework時可以用到. 以下是幾個重要的Topics:

1. C++ Basics

2. Threads

3. Processes

4. Verilog HDL Basics and Logic Design

5. HDL Simulator and FPGA

6. SCREAM 8051 and toolchain

7. SCREAM OpenESL

8. Computer Architecture Basics

這一些Topics本來有些是同學在其他課程當中就修過了的,但是假如您覺得自己還不夠清楚,請自己加強一下,老師只負責簡單介紹。

這學期的上課資料多半會跟去年的類似,但是我會在做一些資料的修正與補充。而由於8051的部分,我們的工具經過一年的修正,加上專題學長的努力,bugs已經少很多了,也就是期末的作業會進行得更順暢,在此向上一屆的同學說抱歉,也向負責的學長說謝謝。

最後,我發現同學對微處理機與計算機組織的支是還太弱,這是硬體系統設計的基礎,希望同學多自己加強,另外就是8051的使用也是本學期的重點,希望同學在微處理機課程裡多用功。

2010/9/12

以下是第一回的投影片, 是有關C++, Process與Thread.

請在這裡下載: C++, Process與Thread

新版的投影片請在此下載: C++/Process/Thread

10/14要繳交的作業內容在新板投影片裡。

2010年12月31日 星期五

與老師的談心時間

為了方便老師跟同學每週上網頁新,我將連結公佈在blog上。
https://spreadsheets.google.com/ccc?key=0Ah21HMqvV0hCdEpBb1RBbldocmRNLXBvM0RTRXJVNWc&hl=en
另外提醒一下,本週(12/13~)碩一的同學通通還沒填哦。
話說,現在blog文章是不是不能透過修改發佈文章的時間(i.e.設成未來時間) 來置頂了呢?

2010年12月30日 星期四

Score Alignment and Following - 小聽

   
[20110223]

‧DTW path onset selection 一個midi frame對多個wav frame的問題
1. midi的ADSR之A第一個值不從零開始,改成0.1。(也許是因為0對noise太敏感)
2. midi onset frame定為A state的中間。

‧MATLAB記憶體不足的問題
1. use memory defragmentation (因為MATLAB需要連續的記憶體)
2. frequency domain用其他的scale
3. others...

‧目前的Cakewalk舊版讀MAPS的midi會有錯

[20110217]

W partial之外的bin設為0的方法。請和2/9的圖來比較。


[20110210]

schedule:
deterministic harmonic constraint -> temperal smoothnese -> spectral smoothnese

[20110209]

同樣是 Friedrich Gulda 的 K 281 - Andante Amoroso
抓了一個低音域的連續八度音片段
 λ = 100, garbage = 1
58.2705Hz的基頻能量非常小,由於圖比例的關係看不出來。
但是實際上它的能量真的很小,且看的出來三倍頻能量比基頻大許多。


後來去看西班牙鋼琴資料庫的一些低於100Hz左右的單音頻譜,
發現也有某些二三倍頻的能量大於基頻許多的例子。


[20110126]

All is 440Hz.
piano : wav
violin : wav
trumpet :wav

[20110125]

P mask, tone model, if else.

[20110120]

Midi note envelope:
Transient part : A= 0.02s, D=0.02s, fixed.
Otherwise, S and R can be scaled.

K281.Andante - 2 bar

1. 將第1、2個template除外的其他template (3rd~13th),給之inital H,
而W的部分先用原本gaussion的initial partial方式來training ,如下圖。

結果:
2. 把3rd~13th template W也用上第一次的結果,如下圖。
結果:

兩者好像差不多...


[20110119]

harmonic bands寬度: 一個半音->半個半音
Mean of all onset difference (Midi synthesized-G Air-2 bars)
0 garbage = 0.057472555 -> 0.057610769           
1 garbage = 0.167695353 -> 0.087274952  (!)

對付實際演奏的音檔,應該還是需要garbage template的存在,
所以以後把bandwidth設成半個半音來做實驗好了。

因此將garbage template 個數1,半個半音的bandwidth為參數,
改變midi envelope為ADSR,如下圖:

Mean of all onset difference : 0.087274952 -> 0.400023036
結果每個onset都變糟了!

以template #14: 440Hz為例,共有三個note,


左圖是簡單的梯形envelope,Diff = ( 0, 0.053333333, 0.022358277 )
右圖是新的ADSR envelope,Diff = ( 0, 0.152018141, 0.376462585 )

看圖,如果把onset的位置像老師說的定在A stage的中間,那麼應該會準一點吧!


[20110118]
Friedrich Gulda - Mozart Piano Sonata K 281 - 2. Andante Amoroso - 3 bars
λ=100
λ=10000
λ=100, 1 garbage
λ=100, 3 garbage

Mean of all onset difference (Midi synthesized-G Air-2 bars)
0 garbage = 0.057472555
1 garbage = 0.167695353

[20110114]
套一個衰減較快的簡單envelope似乎效果比較好一點



[20100112]

今天大家討論之後發現好幾個問題將midi note的能量套一個簡單的envelope,如圖:

目前發現有兩個地方因此有所改進:

1. 對於同時出現的pitch音,在DTW時有了改善,以440為例,在第二小節後半的部分第一聲部和第二聲部同時出現。

原本:

後來:

可以看出在2500的附近path有找到第二個peak。

2. 90度的dtw path 會有 midi frame 一對多個 wav frames 的情況,因此我們需要要訂立一個規則去選擇那一個frame是我們要的,onset部分看起來都是選第一個 frame是最好的,所以假設規則是選最前面的frame,但是在offset的時候卻可能差很多,如下圖。

原本:
後來:
可以看出offset的位置依照規則來選的話結果算是好的。


[20110106]
todo :
1. midi中音符的地方能量改成"梯形"。
2. training一次後,使用initial W : 在某個時間點沒有其八度音的音,initial H : DTW的結果。

貼一下結果圖:



[20101230]

今天大家討論之後發現好幾個問題

1. 音檔比譜高了八度音
2. partial filter bands 忘記inverse
3. 音檔本身高頻就沒有能量
4. 左手應該是Do mi so,比譜多了一個E5。
    (實際用鋼琴測試了一下,應該是有彈mi)
5. 多音可以用garbage template來解決,
    少音卻可能會發生那個template吃掉別人的partial能量的現象。

更正一下結果圖:

‧λ=100的harmonic的效果不夠好,右邊的才有比較好的效果,
   其中第一個template的第二根peak就是 Mi (E5)的基頻。
‧partial數很少是因為音檔本身的問題。
‧目前的五個template是代表 C5、G5、C6、E6、G6
    可以發現八度音和五度音的問題確實會影響很大...


[20101229]

Input : (performance wav , piano )
(按圖可放大)

使用鋼琴的演奏音檔,觀察頻譜發現這個樂器的特性不是f0能量最大而是partial 1。
NMF的結果,對照initial template的圖可以很明顯的發現partial跑掉了,將harmonicity cost function的 λ 加大也沒什麼效果..



[20101227]

Input data:First bar of "Back - Air on the G String" (wav synthesized by MIDI )

Only initial:# partial = 10, Gaussion distribution ( σ = 1)
With additional harmonic cost function (by hanyo):λ = 0.02

The mean of aboutsolute difference between the above two :
W = 1.0837e-007
H = 9.2215e-004

Initial template放了對的頻率之後,有沒有使用harmonicity cost function的結果看起來是差不多的。分的結果看起來不錯,但,也許是因為input是由Midi合成的關係?


[20101221]

論文報告
Parallelism in Dynamic Time Warping for Automatic Signature Verification


[20101216]

將NMF的template設為只能是譜上出現的音+額外具有特殊功能的template,update時加上harmonic的限制。


假設在NMF的結果不錯的原則上,
有兩種方法:

1. 整首歌會出現的pitch都有一個自己的template,得到結果之後,再做單音對單音的 alignment。每個H row,分別去對那個pitch的score,得到自己的alignment。所以音檔裡總共有幾個pitch就會做幾次DTW。

2. 判斷那一個時間點有哪些音,template的個數和其代表的pitch會隨之改變。不做DTW,直接將H的值來分析結果。



[20101213]

●  純MATLAB  code的加速:

本來程式是依照這樣的公式寫,很直覺的就是用for loop針對matrix的每一個element去做計算。


 後來依照我11/23所報的第一篇paper上面的公式,他把它寫成更矩陣的形式。

 [ref. Accelerating Non-negative Matrix Factorization for Audio Source Separation on Multi-core and Many-core Architectures]

改寫後在matlab上跑,參數:frame size = 8192,hop size = 256,# of templates = 10, # of frames = 769。
只計算update部分的時間,iteration = 100次。

origin : 297.644882 (sec)
modified:28.522258 (sec)
speedup:10.4355倍

竟然差了十倍,看來在matlab上真的要盡量用矩陣運算來取代for loop寫法!


●  在MATLAB上使用CUBLAS library的SGEMM(Single-precision GEneral Matrix Multiply):

矩陣相乘維度參數 m x k x n
假設 C=A*B,A : m x k,B:k x n,C:m x n

每一列的意思:
  • MATLAB : 使用matlab指令A*B
  • myAPI:我寫的matlab函式,透過MEX-file得到matlab的參數,因為matlab是double-presicion,要先轉換型態之後,再去使用cublas library,之後再把值傳回。
  • Speedup:MATLAB time / myAPI time
  • only CUBLAS:myAPI中,不去計算matlab矩陣轉換到cuda矩陣的時間。
  • only cublasSgemm:only CUBLAS中,不去計算allocate cuda memory和搬運的時間,只計算lib中矩陣相乘函式cublasSgemm的時間。

左邊的參數會這樣設是仿造目前的參數W*H 來的,但這樣使用CUDA反而比MATLAB還要慢;右邊的實驗是想說資料維度大一點或許就會比MATLAB來的快,結果也如我想的。

接下來如果真的要使用mex & CUDA,應該不能一次矩陣相乘就呼叫一次,因為這樣資料要轉換型態、記憶體allocate還要搬好幾次,不划算。應該要寫一個把整個NMF過程都包含進去的API,最好是整個NMF都在GPU memory上面運作就好。

猜想11/23報的第一篇paper會比後面兩篇speedup來的小的原因是因為,他把每個operation拆開,每一個都寫成一個kernel function去執行,而後面兩篇可能是一次把事情做掉吧。




[20101206]

在Matlab上使用CUDA,可以參考Nvidia提供的pdf。
White Paper - Accelerating MATLAB with CUDA™ Using MEX Files

如果只要使用cuda提供的library,(ex. cufft)...等,那麼只需寫成.c檔就好了。
>> mex filename.c -IC:\CUDA\include -LC:\CUDA\lib -lcudart -lcufft
成功的話就會被compile成MEX-file(.mexw32)。

如果需要自己寫kernel function,要寫成cuda特有的.cu檔案才行,之後交給nvcc去compile。
這時候需要使用一些plugin tool。

A Guide to Using NVMEX tool


可能因為os、matlab、vc版本不同,在這邊會出現一些錯誤。

首先,我使用的是VC9,但範例中是VC8,因此需要修改一下nvmexopts.bat的一些路徑,
怎麼修改請看此pdf中的第6點 (連結)。


再來出現的錯誤
nvcc fatal   : Unknown option 'oC:\Users\Vivian\AppData\Local\Temp\mex_F9gfIA\test.obj'
看的出來因為路徑前面多了一個o所以找不到所需要的檔案。

只好去看一下nvmex.pl,把perl中的一些變數印出來看,發現是
$name_arg = $NAME_OBJECT . smart_quote($target_name);
$NAME_OBJECT這個變數的關係。

解決方法是把nvmexopts.bat中,
set NAME_OBJECT=-o 改成  set NAME_OBJECT=
也就是不給它值,就不會被干擾哩。


之後再compile,會發現會出現很多錯誤訊息,
google之後找到nvidia forums 有人和我有相同的問題! (連結)

將 nvmexopts.bat 中,
set COMPFLAGS=-c -D_WCHAR_T_DEFINED -Xcompiler "/c /Zp8 /GR /W3 /EHsc /Zc:wchar_t- /DMATLAB_MEX_FILE /nologo"

"/Zc:wchar_t- " 改為 "/Zc:wchar_t",也就是把"-"去掉,這樣雖然會出現一些warning,但是就可以compile過了!

感謝討論串中的eigma大大。



最後小小測試 fft v.s cufft,speed up大概是1.5~2.5左右。



[20101123]
報告
NMF on CUDA


[20101115]
實作chroma方法on MATLAB,依照Multi-pass...那一篇paper。
Frame size = 8192,hop size = 2048,DTW使用type I,與PSD的一樣。
平均差異值來看好像PSD好上一點,但PSD遇到長音感覺比較容易出錯,且chroma的異常值比較少。chroma在第344個錯誤可能真的是因為那個音的onset的能量太小。

但是在兩個paper中,有一點比較不一樣的地方是在DTW三個方向的weight。
PSD : (w0, w45, w90)=(1,2,1)
Chroma : (w0, w45, w90)=(1,1,1)
有點trick的是,因為是比min,(1,1,1)這樣的weight會比較傾向於走45度角,應該要讓它大一點畢竟走的距離是比較大的,可以看DTW path右上角的小小方區塊,一個走水平方向一個走斜對角方向,可能是此原因造成的差異,也許兩種都改成(1, sqrt(2), 1)會是比較公平的比較。


[20101112]

經由DTW path反推出alignment onset,與之前標的比較。圖為和alignment之後得到的onset與groundthruth onset比較的difference。
另外,因為使用的是typeI的DTW (0, 45, 90度),所以有可能會有一個midi frame對多個wav frame的情形,下圖分別是取中間frame、第一個frame、最後一個 frame來做為比較的差。

difference error (seconds):
每個frame之間距離2048,所以resolution大約是46 ms。

以下以取中位數frame的情況來分析,數字代表音符的index;
如果說去除大於1.5秒的那3個值,重新計算difference平均 = 0.0937 s,大約是兩個frame 。


第344個音符是BWV1007這曲子中,中間長音之後的第一個音符,在演奏的音檔中,這個音符的onset音量很小。

而第655、656個notes是曲子的結尾,是長音。


接下來有點想要在matlab上實作一次chroma的方法,比較一下這兩種方法對於BWV1007的結果如何。

[20101108]

Implement 6月7號所報告的論文,使用Matlab...令人感動的方便許多。

Midi parser的部分感謝這個網站與它的主人

經由midiInfo可得到每個note的資訊([track chan nn vel t1 t2 msgNum1 msgNum2]),之後再利用他的piano_roll,此原本是用來畫圖的function,我們丟進適當的時間間隔參數(hop的時間長度),就可以視為是我們的譜的roll,接著用回傳的PR矩陣,可以知道每個frame有哪些音符,再利用它造出我們的filter。每個note有8個bandpass filter,bandwith為一個semitone。

依然是先使用Bach BWV1007 prelude做實驗,wav是2分44秒,共656個notes。
圖中藍色線為spectrum,綠色線為band filters。上圖是wav的第2個frame vs midi的第2個frame,distance較小;下圖是wav的第10個frame vs midi的第220個frame,distance較大。

論文中的hop size為256,所以有5.8ms的resolution。
可是如果這樣的話,matlab記憶體會不夠,因為矩陣變得相當大;且論文中提及他實驗的一首兩分半的巴哈小提琴獨奏,就需要2GB的記憶體,但筆電的RAM也才2GB...

所以先使用frame size = 8192,hamming window,hop size = 2048。

左邊是distance的矩陣,顏色越深代表越相似;
右邊紅色線是DTW找出來的對應路徑,0度, 45度, 90度的 typeI,weight=[1,2,1],頭對頭、尾對尾;此外記錄一下一些參數 thetaD = 0.5, thetaS = 0.5, ss = 1, sd = 1。
可以發現結果和左邊用肉眼看出的由distance小的element所那條組合成的線很相近,不過這也只能說是DTW找出來的path和最小cost真的很符合而已。

要知道結果好不好,還是要和ground truth(之前用cool edit標的)比較,下一步應該要把cue的資訊弄進matlab計算正確率。


[20101026]

報告
Artificial Neural Network: An Overview
投影片


[20100928]

論文報告
A Multi-Pass Algorithm for Accurate Audio-to-Score Alignment
投影片


[20100802]

論文報告
Improving Polyphonic and Poly-Instrumental Music to Score Alignment
投影片


[20100608]

Q:
我有一個spectrum,已知裡面的某一個f0,想要知道它是不是單音且為harmonic ?
A:
1. filter : 因為知道f0,在每個倍頻上用 gaussian 去 model 每個 peak
2. 計算 : spectrum 的總能量 - spectrum 經過 filter 後的能量
3. 如果是單音且為harmonic,那麼剩下的能量應該會很小。


[20100607]

論文報告
Alignment of Monophonic and Polyphonic Music to Score - Ircam.
投影片

除了之前看的chroma feature,也有好一些人是使用這篇論文提出來的方法。這篇論文是2001年publish的,它提出了一個名為 Peak Structure Distance(PSD) 的 feature,這個Distance用來當作DTW中的local distance使用,相對於之前我們的作法就是用來取代Euclidean distance。

PSD簡單來說,就是去算score frame與 audio frame 的peak的相似度,越相近distance越小。另外它還model了一個note的開始 (attack model) 與 結束 (silence model) 。

它做了很多仔細的實驗和數據,結果看起來不錯,感覺上還蠻值得參考的。下次會看也是由Ircam在2003年發表的paper,關於這個方法提出的改進。


[20100604]

以 Mozart piano sonata K.545 的前四小節為測試曲子,修改 midi 來合成測試的 wav。
Midi 合成 wav 軟體 : WinGroove

目前ground truth : Calkwalk 看 event list -> Cool Edit 人工標記
(未來:不執著於要存到wav裡的cue,用另外的檔案代替儲存。)

新增輸出 onset error 詳細資料的 html table。

測試了合成時有無reverberation、某個時間點譜不只一個音出現但audio其中一個音比譜晚出現半拍的情況。

進度投影片
link


[20100521]

由於想了解DTW在一些特定的情況之下會有怎樣的行為,因此我用midi式的chroma feature來作實驗,測試了比原本的 chroma 多音、少音、平移幾個半音,對於兩種 type 的 DTW 會有怎樣的結果。

另外也測試了 piano 與 trumpet 的片段。

進度投影片
link


[20100503]

論文報告
Handling Asynchrony in Audio-score Alignment
投影片



[20100430]

現在的目標,是讓score alignment夠準,然後能自動截取audio中每個音的起始時間,還有結束時間,它的f0和partials的frequency、amplitude,來做合成使用。

新增輸出 cue 詳細資料的 html table、輸出 alignment 結果所對應的midi、wave 之 frame、second 的 html table。

程式有bug待修。

進度投影片
link


[201003022]

論文報告
GPU ...



[20100204]

兩件事情:解決讀midi的bug、score alignment的onset時間 v.s 人工標記的onset時間。

1. 讀midi的bug : 在某些時候會少讀了一些長度
發現依然是讀檔時,byte轉換發生的問題,java的byte是signed,所以當值大於127它就會變成負的,再去做排列就會錯。這個問題之前也發生在讀wav的時候,用一樣的方式解決就好了。

更正一下上次po的圖,BWV1007前兩小節(點圖可放大)
midi :
wav origin :
wav considering partials :


2. score alignment 結果的onset時間 v.s 人工標定的onset時間

FFT frame size : 4096
hop size (兩個frame起始位置間隔) : 512
表格裡面的值 (秒) :
|score alignment 結果 - 人工標定的onset時間| / 總共onset個數


可以發現前四組結果,有考慮partials的方法會比沒有考慮來的好一些,
但是如果是整首BWV1007來做比對,兩者結果都變差許多,而且有考慮partials的方法結果還變得比沒有原始的方法差。

對於整首的這組結果來觀察,發現平均值增大的原因可能是因為有幾個onset的差異比平均大許多,大概一秒鐘左右。而有考慮partials的方法差異大的onset比原始方法的這種情況還要多。

新方法大約310-343+後面24個onset誤差較大,原始方法大約323-343+後面20個onset誤差較大所致。第343個onset對於BWV1007剛好是歌曲的段落,是一個長音,而且BWV1007這首歌除了中間和最後的兩個音是長音,其它都是16分音符,不曉得是不是因為這個原因讓判斷變差。


[20100120]

論文報告
Music Score Alignment and Computer Accompaniment
投影片


[20091231]

BWV 1007前2小節對譜全圖 (點圖可放大)
沒加新方法的 wav :

有往上加 partial 的 wav :
midi :

可以看出,有加了往上疊加 partial 能量方法的對譜效果比較好,
最後面的部分沒對好,是因為 midi parser 那部分有些問題,最後面少讀了一些音。
所以接下來要幫 midi parser 的部分code debug。
→ check 完學長原本的 c# 程式應該是對的,所以可能是改到 java 的時候不知道哪裡改錯了...  (20100105)


[20091221]

首先是解決冠廷學長之前沒處理到的部分:由於 map 到每個 pitch class 的 bin 數量不會一樣,所以要做一次 normalize 的動作。

左邊圖片是原本的,右邊是有加上取平均。(也就是傳統chroma)
1. white noise
2. BWV1007-15s

之後就作新加的部分,要往上加 partial 能量,也加上了 normalize 取平均的步驟。
以 BWV1007 前 15s 為例:
1. original
2. 每個 bin 從 frequency domain 中找最接近的partial's bin,加總其能量並取平均。
3. 每個 pitch 從 frequency domain 中找最接近的 partial's bin,加總其能量並取平均。(花較少時間)
目前以第三個方法為主。

上面三個圖之間似乎沒有很大的變化,
第二個比較稍微不一樣一點,第一個圖和第三個圖只有些微差距。

令人在意的是第二個音,譜是 RE,但是卻是五度音的 LA 能量較強,用了新的方法依然沒解決這個問題,這蠻出乎意料的。後來印出一些資料來看,發現可能是threshold設太小的問題。

這個threshold是用於判別這個bin是不是目前基頻的partial:
| (bin frequency/基頻) - ((bin frequency/基頻)最接近的整數) | <= threshold   所以我試著將 threshold 從0.001 調整為 0.1,第二個音 RE 就出現了! 對譜的結果也比之前的好



[20091217]

論文報告
Audio Thumbnailing of Popular Music Using Chroma-Based Representations
投影片


[20091216]

與老師討論了一下,以後可能有兩個方向可以走。

1. 假設 midi 是對的。
我們可以經由 DTW 的 cost 去調整 partial 的比例,也可以說是 chroma template 的 weighting 參數,以貼近現在樂器的特性。
比如說現在這把大提琴第三個partial的能量會特別高,希望可以經由 DTW cost feedback 來調整我們的 chroma template 的參數。

2. 假設知道是什麼樂器,而且只適用在這首歌只有一種樂器上,但是這樂器可以是多音。
(1) 把 midi 經由這樂器的音色庫,合成出符合這樂器的 wav,轉成 chroma 後再進行對譜。
(2) 由 wav 來建 instrument model,藉由這個來讓 chroma 更準確。


[20091211]

看了老師的回應,和小明學長討論了一下,預計的做法是:
FFT(4096) -> map 2048個bin到最接近的 pitch -> 每個pitch從frequency domain中找最接近的partial's bin,加總其能量,取平均。

這樣應該會減少一些計算量。


[20091209]

為了解決五度音等partial重疊導致能量貢獻給別的音名的問題,但是又想要維持使用chroma,也不想要在這裡使用pitch detection等較複雜的演算法。經過討論之後,決定現在多一個步驟的做法:讓每個頻率往上找它的partial,把其能量加起來到自己身上,這樣重疊的partial能量就會貢獻到可能是它的f0的身上。

流程 :
FFT (size:4096) → Map 每個 bin 到最接近的 pitch frequency → 每個 bin 往上找倍頻的能量並加到自己本身 → 每個 bin 分配到 chroma vector

我們使用的pitch frequency table是參考wiki的音高頻率表

另外就是這個演算法花的時間很久...

結果:
發現最下面那條Do的pitch class的能量一直非常大。

後來發現是因為第一個bin大約是10.7666Hz左右,然而第一個bin一定是所有bin頻率的因數,對照pitch frequency table,10.7666Hz最接近的是C0(DO),因此它的能量因此會最大。

忽略了第一根bin的結果:
發現變成是往上數第六條的能量最大,對照音名是FA。這是因為第二根bin也是好多bin們的因數,第二根bin頻率大約是21.5332Hz,對照表最接近的是F0,因此得知。


後來和小明學長討論發現了另一個問題,都是關於應該需要去取平均的地方。

1. 冠廷學長做Chroma的方式,如果是採用每根bin就map到跟它頻率最接近的那個音之後加起來,那麼事實上他可能忽略了一個問題,低頻的部分兩根bin中間可能有好多的音在那個範圍,在高頻的部分可能在兩個音的範圍中間會有好多根bin,因此會有每個音所擁有的bin會不同數量的問題,我們實驗用white noise當作input,真的發現chroma的顏色並沒有分布的很均勻。所以應該要讓每個音除以它所擁有的bin的個數,取平均。

2. 在我們新加的方法中,低頻的bin會有較多的partial,所以能量加到自己身上之後,應該也要除以partial的個數來取平均。雖然這樣當能量懸殊的時候還是會造成彼此相對的差異減少,不過總是比沒有做normalize來的正確一些。



[20091201]

用BWV1007前四小節去跑,發現wav chroma錯誤了。
1. 前兩個音SO(低)、RE的部分,推論是因為五度音的關係,f0相差1.5倍,因此倍頻重疊了,RE的部分能量被認為是 SO 的。
2. 後面四個音也錯了,變成都是LA,推測是因為frame size不夠大,造成 fft 後頻率域的resolution不夠高。

origin frame size : 2048

frame size : 4096

frame size : 8192

可以看出增加frame size以增加frequency的解析度,結果準確許多。
不過第二個音 RE 的部分為什麼chroma顯示出來是 LA 的能量最強呢,是因為 RE 和 LA 是五度音嗎?
但是觀察spectrum,發現440 Hz左右真的有一條能量強的partial,所以不只是 RE 和 LA 第一個重疊的倍頻880Hz所分配給 LA 的部分。
→ 440Hz是這裡的 RE(146.83Hz) 的三倍頻沒錯,之前誤以為是它的高八度 RE(293.66Hz) ,而它的三倍應該是880Hz,所以才會疑惑為什麼會有440Hz的強能量。(20091202)

(按圖可放大)
另外,SO 的能量一直很強,造成餘音的效果。雖然譜上看起來是單音的樂曲,但是實際上是多音。可能是因為樂器的特性,第三個partial的能量特別強。

目前把頻率域的值map到chroma gram的方法是,準備一個10個八度音的frequency tabel,然後就去對和哪個pitch最接近,再map到chroma vector。
這樣的方法,五度音的partial能量會分配給兩者頻率較高的那一個。ex. RE (293.66Hz)的第三個partial、LA(440Hz)的第二個partial,大約是880Hz,而880Hz對照frequency tabel是LA。
但是學長也提到,如果採用傳統f0 detection的投票方法,那麼五度音的重疊partial能量會分配給兩者頻率較低的那一個音。

學長建議,接下來有兩條路。
第一條路,去解決五度音在chroma vector上表現的問題。
另一條路就是略過五度音的問題,找個沒有五度音的片段,往下找DTW在對譜時所展現的特性,也就是找DTW在對錯譜前後的參數變化情況。



[20091128]

把DTW 的matrix印出來。
本來是要印成文字檔,但是實在不好觀察,所以就做了另一個可以輸出成HTML的版本,這樣可以用簡單的方式去讓印出來的tabel上色和排列。

不過table真的很大,光是一分多鐘的dtw table的txt檔案,就可以達到450MB左右。
以下是用BWV1007前四小節的結果。

type 1 :




type 2 :


粉紅色底的格子是代表dtw找出來的path。



[20091124]

標音檔的SOP(手稿)

工作畫面
上方是cool edit,左邊是cue list(Desc欄寫pitch),下方是catwalk,主要是拿來顯示譜。


[20091122]

標好了巴哈無伴奏大提琴BWV 1007 Prelude,大約兩分五十秒,655個音,655個cue。
每個cue我都給他一樣的長度(4096個sample),因為要抓住那個音是哪個瞬間出現的有點難,所以後來決定去抓換音的瞬間,因為換音耳朵比較好辨認,所以我想起頭音的時間點就設cue的中點。

小筆記:
1. 20小節的地方音檔或譜似乎有錯,
音聽起來是do# la mi fa so mi fa so
譜是do# la do re mi do re mi
觀察DTW的時候可以注意一下這地方。
(應該是midi錯,因為去找過youtube上面的影片聽過跟wav是一樣的)
2. 發現mi不知道為什麼波形amplitude都比較大
3. 同一個音連續出現的話有點難聽出onset,所以是看波型來標。

之後,用之前的java程式去跑跑看,在作DTW一直出現例外 java.lang.OutOfMemoryError: Java heap space,有試著逐步幫JVM加大他的記憶體,但是還是出現一樣的例外。
所以我就想知道這樣的長度DTW到底需要多大的記憶體,就用學長之前的C#程式去跑,發現DTW大概吃掉1.5G左右的記憶體。可是給JVM這麼大的記憶體參數,會顯示無法建立的訊息。

目前wav的frame size是沿用學長的2048 overlap 512,想改成4096 overlap 2048,這樣可以減少frame的數量。此外midi是用一個tick當作一個frame,所以frame的數量很大。因此兩者所構成的DTW matrix使用的空間是很大的。



[20091112]

論文報告
An Efficient Multiscale Approach to Audio Synchronization
投影片



[20091023]

讀cue的程式寫好了,用 java去改寫,因為想說之前的chroma部分也是用java來做。
結果大概如下圖,測試的是原本語音的檔案。



因為我們的目的是要知道onset,所以對於cue來說,我們需要的就只是某個cue的起始時間。所以學長建議我,在幫音樂wav標onset的時候,cue的長度用很短就可以了。

現在我先著手標記巴哈無伴奏BWV1007的onset,因為它是單一樂器,而且它的節奏不會很快,可能會比較容易。現在覺得有個問題就是...要抓住並判斷音出現的那瞬間真的有點難@@


[20091006]

為了可以在wav上面標記出正確的onset作為比對資料,和小明學長去了吳老師實驗室詢問了一下,知道了可以用cool edit直接在wav檔裡面記錄cue list,方法很簡單,就是用滑鼠選取這個cue的範圍,然後按下F8就可以了。

學姊也給了一隻他們之前寫的程式給我,是用VC6+MFC環境寫的關係,還有它的output有用到資料庫,我的電腦上執行不起來,所以想說自己來改寫一個。


[20090924]

論文報告
Polyphonic Audio Matching and Alignment for Music Retrieval
投影片


[20090924]

學長的程式已經轉換到java完畢。
以前的程式架構,是每個步驟都是分散手動進行。


然後我現在把它整合在一起。

Improvement :
1. 整合、連貫各個project的功能。
2. 自行從GUI選擇讀取的檔案,不再受限於固定名稱。
3. draw onset frames
4. 可以使上下兩個scroll bar同步移動方便對照


程式畫面和流程 :



[20090908]

學長的MidiParser專案轉換到java已完成,得到的結果也和學長的一致。bug仍然是出在byte的問題,不過由於上次的經驗,這次解決就快多了。

這個專案的功用是:讀取midi file並分析,得到midi的chroma,也輸入了上個步驟得到的wav chroma,將兩個chroma做DTW,最後輸出onset的資料。

另外發現學長midi的delta-time(variable-length quantity)算法好像有些錯誤。這部分還需要find out。

→ 學長沒有錯,是我誤解code的意思。 (20090909)

[20090831]

首先確定JAVA和C的input stream對於wav值都是使用同樣排列方法。


使用上次說的網站的方法去做會有問題,因為它這樣出來的值全部都會是正數,這樣不是我們想要的結果。所以我們要偵測第二個byte的highest bit是0還是1,如果是1的話,代表這是一個負數,所以我們在幫int的最高和第二高的byte補上1。

由此得到的int就是我們要的sample。和MATLAB的值對照過,兩者是相同的。



另外這是如果我們每一個sample想用short去存的方法。(最初是用short)



比起最之前的寫法,是多了把在smaple裡的lower byte & 0xff 這個步驟,因為這樣可以先確保他會先轉換成是一個positive的int,再轉換成short,這樣值就不會錯。如果直接轉換的話,他可能會認為byte值是負的然後就轉換到一個不正確的short,之後higher byte再往左移8 bit之後合併數值會有問題。之後也確認了這個方法與MATLAB的值一致。

最後使用的是網路上找的java FFT code,學長使用的FFT code的結果,虛部會差一個正負號,但是因為我們用的是能量值所以不會影響到chroma。不過我不確定我找的那個是不是open source,能否自由使用...

能解決這個問題感謝DNA與小明學長的幫忙。接著我開始來改MIDI Parser的部分,找到了java有提供javax.sound.midi這個package,試看看能不能拿來在這個部分使用。


[20090824]

把兩邊程式的FFT結果印出來,發現值真的不同,著手改寫冠廷學長使用的c# FFT sourse code改成JAVA,錯誤還是存在。後來小明學長建議用MATLAB裡的wavread還有fft function去做,把從MATLAB得到的wav還有fft值分別和C#、JAVA讀到的wav之後用MATLAB fft做的結果去比較。

結果是發現JAVA的是在讀取wav檔的值就有錯了,每一個frame裡錯誤的個數、index都不一定,錯誤的element值和正確的值相差的都是256的倍數,目前測試結果最大可差別到256*8=2048。猜想可能是overflow之類的問題。

Google到這個網址,Reading and Writing Wav Files in Java,它說因為JAVA不像C語言,沒有unsigned type的設計,都是two's Complement,所以使用java的File-IO得到的資料還要經過處理,他提供的解法是比如說2 bytes的short 就用4 bytes的int來代替,int用long來代替。這個可能就是我們的問題所在,會用此方法來試試看。



[20090818]

與冠廷學長交接之後,開始著手改寫程式從C#轉到JAVA,這是為了將來可以使用在authoring tool上。目前改寫至可以運作的部分有:
1. Read wav file → FFT → Chroma Vector
2. Music Library

但是比對我的程式和學長的程式對同一個wav檔案所轉出來的chroma,發現能量最高(=1, because of normalization) 的地方在某一時間區段是不同的,後來覺得只比對能量=1的地方好像不是很好,所以以下是用圖片來呈現。發現c#的結果乾淨許多…

c#







java






由於學長程式的FFT是使用c#的open source code,我目前java的版本也是先使用外面找的java code,所以推測可能是在FFT這步驟出現不同所以導致結果不一致。老師建議把先FFT的結果印出來作驗證。



[20090714 by SCREAM Lab, NCKU, Taiwan. 位於 下午 6:08]

在MIREX2008裡面有一個比賽項目叫做Score Alignment, 網址如下:

MIREX2008 Score Alignment or Score Following

其實就是冠廷學長的論文其中的一部分. 冠廷用的是Chroma Feature, 其論文我們過一陣子再Post出來, 但是我們一貫的討論可以在下面看到:

冠廷的Polyphonic Music Information Retrieval

這個問題對我們很重要, 不過一般的Score Alignment做的要是能從頭Follow到尾, 也就是冠廷做的. 研究上當然是要如此完整, 但是假如以短時間內能用到我們要做的應用, 那麼是可以有一些妥協的. 比如說, 我們可以讓使用者把一段Wave框起來, 在讓它來對Target的譜子, 而且一次只要對一部分的譜就好, 例如四小節, 八小節, 長短就看我們的演算法的好壞.

這個串今天由我來起個頭, 接下來就由小聽來接續. 我建議可以將冠廷學長的方法先弄起來, 然後找其他人的論文來Implement, 久了後, 相信會越做越好, 也許有一天我們也可以去參加比賽.

另外就是Score Alignment會是Authoring tool的一部分.