語句的呈現與連結

在準備每一次報告的時候,我總覺得老師特別要求的是一種話語之間的連結感,是前後文的串接性、語句的對稱性,還有每個篇章主題的架構性。我的本性應該完全不是這樣的,可能是神來一筆的說這句,又可能是隨性所至的擴展篇幅,而最糟的情況是腦袋空空一片,只能站在台前結巴。我想報告絕對是某種層面的溝通,我想你應該最明白不過了。並不是每個人都有耐心與心思去理解你的個性,甚至你的詞窮,你的隨性所至。每一次上台都是一個殘酷考驗,要不就是好好的講完,給予聽眾好印象。要不就是台下聽眾看你的窘迫,暗自帶著竊笑離開。

文字與心思莫過於此。當你講出「隨性」,那聽起來像大概有九分正面。而「恣意」這種字眼,就又顯得貶意十足。當你形容一個人是「隨性所至」,又或是選用「恣意妄為」,所謂的認知與印象就大相逕庭。即使所形容的人是那樣唯一而特殊的存在,就因為敘述與表現上的不同而硬生生地在印象層面分流。

我們沒有耐性瞭解,因為你必須選擇最好的呈現。所以,我必須完全看見你眼中的迷惑與遲疑,因為那將成為我字字斟酌的指引。

==

今天聽了 Muse 的幾張專輯,最喜歡的大概是 Hysteria 跟Uno 了,我想我喜歡他們勝過 RadioHead 吧!

今天沒有跑步,沒有練琴,我累了。

那可能是美樂

第一次遇見美樂是在 2005 交大星聲社的搖滾祭。那年的搖滾祭是在風城廣場前的大舞台,其實距離那一天已經非常久遠了,我卻好像還記得那一天的微小的細節。像是,showmind 團主唱小光邊喝美樂啤酒一邊唱著「無敵鐵金剛」;又或者是某熟識的鍵盤手選錯了音色;還有本片同學強而有力的鼓擊;又或者是我同學獨自站在角落的身影。

老實說我不記得美樂那天的樣子了,也不知道為什麼她叫做美樂,也許是取名自小光喝的啤酒名,也許只是個巧合而已。我只記得她說:「你學弟貝斯彈得不錯耶」。

再遇見美樂這種事情,我想我應該是壓根想不到的吧。這種事情到底是命運走向了你,還是你走向了命運,以我這微薄的思緒來說,這終究說不明白。總之,我在下班的路上遇見了她,而看見她就像回想起當天的記憶一樣,遙遠而難以確定。我應該她應該可以明白這種模糊的感受。

我說:「太多巧合拼湊出現在的我,四年前我學弟的那把貝斯,現在在我這邊。那年我聽不出貝斯的聲音,現在我稍微瞭解一點。回想起那天,雖然遙遠,卻是緬懷多於想念。這種感覺,大概跟回想童年是兩種迥然不同的感受吧。」

你笑了笑,說:「好像有什麼東西回到你的身上了。」

「是嗎?這麼確定?」

「沒有,只是感覺而已…」

對話結束的時候我搭上往動物園方向的捷運,只不過,這次好像還帶著另外一個自己。那可能是美樂。

Discogs: 一個社群性的唱片資料庫

不知道你有沒有這種經驗,買了一張 CD 回家,興高采烈的想要轉成 MP3 或是 FLAC,結果 freedb 壓根子找不到,最後還得到官方網站去把曲目資訊一個一個的重新 key 進來。其實這也不能責怪任何人,畢竟把唱片的曲目資訊整理進 freedb 本來就不是什麼理所當然的事情,這大概只得靠社群性中唱片擁有者的熱情才能做到。

我曾經跟幾個朋友說,為什麼 CD 市場中比較少像是 aNobii 般的社群網站呢?你可以給予評分、可以交換、也可以在資料庫中新增最新發行的 CD 資訊,在這個社群中每個人都可以是審核者(Moderator),能審核一張專輯資訊的正確性,也同時是貢獻者(Contributor),提供專輯的所有資訊,可能包括類別、製作人、發行日期、甚至每首歌曲的詞曲創作等。而這些資訊可以被應用在各種地方,像是數位音樂的標籤(Tag)上,以及專輯資料的數位化上。

Discogs 就是這樣的一個網站。最早留意到這個網站是在 Mp3tag 的使用上,他能夠從 Amazon.com 以及 Discogs 取得曲目資訊,並幫你 Tag 到音樂檔中。

以前來說,我總覺得 freedb 就已經夠好用了,但總有一些意外,例如 Sarah McLachlan 最新的專輯 Closer: The Best of Sarah McLachlan 似乎就會因為某些曲目的刪減(因為發行的地域性,日本專輯格外容易出現這種事情),造成 freedb 找不到專輯資訊。這點 Discogs 就顯得人性化許多,你可以搜尋一張專輯,然後視情況改變其對應關係。像是

foo_discogs screenshot

就可以把最後三個 DVD 的資訊給移除掉,讓 Discogs 把前 13 首歌的資訊寫到對應的檔案上。

我覺得 Discogs 比較人性化的地方上是,他並不是用曲目上的「時間」資訊來判斷專輯的,而是靠著使用者輸入說「這張專輯是哪個歌手」、「專輯名稱大概是什麼」,再讓使用者從資料庫裡的資料來標記音樂檔。因此,使用者也更有彈性,能夠選擇適合他語系的資訊、適合手邊專輯版本的資訊進行標記。對開發者而言也顯得更相當友善的是,他也把 API 開發出來供大家使用,目前 Perl 也有 WWW:Discogs 可以使用。

不過開放的平台最大的問題也莫過於「管理」以及「社群貢獻」上,目前 Discogs 的中文資料應該非常少吧,前幾天我也才剛把陳綺貞的「太陽」送上去,但目前還沒有人 Vote(還是非常戒慎恐懼……)。所以說,如果你買了一張正版專輯,也許你也可以考慮把專輯資訊送上去,讓更多的人能夠使用你所貢獻的資料,也讓這些資料在十年、二十年之後還能繼續留存下來。也許就像 OpenStreetMap 的概念相似吧,開放而美好。

忘了說,目前支援 Discogs 的軟體有

個人私心推薦 foobar2000 的 foo_discogs,也許下次當你買了一張專輯,正煩惱找不到專輯資訊時,試試 Discogs 吧,也許會有意想不到的收穫!

YousableTubeFix 給你高畫質的 youtube

YousableTubeFix 是一個 Greasemonkey 的 script,他做的事情還蠻多的,除了能幫你下載 youtube 的影片之外,最好用的莫過於以下拉式選單讓你選擇 standard Low Quality FLV, MP4, High Quality FLV or High Quality MP4 這幾種格式,讓這個 HD 的世代能有比較好的影音體驗。

雖然你還是可以用老方法,手動去改 fmt 成 18 或者 22 看看,不過我還是喜歡用這個 script。而且你可以比較一下畫質上的差異,第一張是一般品質,第二張則是 High Quality MP4,我想應該高下立判吧!

KOH+ 最愛,一般品質

KOH+ 最愛,fmt=22

不過 fmt=22 的狀況下,你的電腦也需要強力一點的 CPU 才放得動,以我現在這台 Pentium-M 1.3G + 512MB 的機器,實在很沒辦法阿….

圍巾與手套

有同事說我寫的東西都太繞口了,那就寫一些不繞口的吧!

高中的時候,因為念的是男校,我們那群男生間總有一些奇怪的文化。其中一個就是,那些冬天圍圍巾的同學總是會被冠上 gay 的名號,像是 gay 熊、gay 猩……。所以在那段期間,我從來沒有想過要買圍巾,也沒有想過要買手套。

上了大學之後,我總覺得新竹的冬天尤其冷,但大部分的時候,我也只是狂喝熱水試著讓自己溫暖一點。

畢業回到台北之後,也許是視網膜效應吧,我總覺得圍巾在搭配上能加分不少。

而第一次圍上圍巾是上週六陳綺貞演唱會那天,我才覺得,第一次覺得原來把脖子圍起來是多麼幸福的事情。看著「嫌疑犯 X 的獻身」中的石神圍著圍巾,緊緊地將口鼻給包覆住,原來在這樣的冬夜裡,圍巾是能給予我們緊密而溫暖的重要物品。也許就因為外在是那樣的寒冷,那簡單的幸福就更顯得可貴了。再仔細想想,我那高中時代的堅持就顯得可笑而無關緊要了。

初探 TR1 function object

最近的專案常常需要更新 INI 設定檔,而最麻煩的事情莫過於太多零散的設定,你必須要記住 INI 檔設定的 key,再把在某個 object 的 member function 把值抓出來,最後再丟給 WritePrivateProfileString 之類的 function 把值更新進檔案。

所以常常就會寫出一堆噁心的 code 像是。

    obj.iniKey = "INI_SERVER";
    obj.iniValue = info.GetServer();
    UpdateByObj(obj);

這樣的話,有幾個設定就要寫幾次,所有的 Key 跟 Value 的相關性都顯得零散,未來要加上新的設定,也非得要再加上類似的 code 才行……。

忽然我就靈機一動,也許可以用 tr1::function 跟 tr1::bind 來做這樣的事情。

    struct proxyConfig
    {
        std::string iniKey;
        std::tr1::function<std::string()> func;
    };

    const proxyConfig configArray [] =
    {
        { "INI_SERVER", std::tr1::bind(&proxyInfo::GetServer, &info) },
        { "INI_PORT",   std::tr1::bind(&proxyInfo::GetPort, &info) },
        { "INI_USER",   std::tr1::bind(&proxyInfo::GetUser, &info) },
        { "INI_PASS",   std::tr1::bind(&proxyInfo::GetPass, &info) },
    };

    for (size_t i = 0; i < sizeof(configArray)/sizeof(configArray[0]); ++i)
    {
        obj.iniKey = configArray[i].iniKey;
        obj.iniValue = configArray[i].func();
        UpdateByObj(obj);
    }

靠著把 INI 的 key 跟 member function 建表就顯得簡單一點,並把更新的程式碼簡化成一份,未來如果要新增不同的設定,也只要更動表中的 INI key 跟所綁定的 function 就好。

不過後來仔細想想,其實只要在建表的時候寫成 info.GetServer() 就可以滿足我的需求了。

而 tr1::function 與 tr1::bind 絕對不是只有這點小技倆而已,真正使用的巧妙應該是 C++ Function Objects in TR1 所提及那種彈性而優雅地將 function 包裹成物件,能有改變的彈性,也能應時應地做出適合的調整。

如果你的編譯器還不支援 tr1,除了換一個之外,你還可以考慮一下 boost,也許更瞭解一點,會讓你的生活變得更好歐。