如何用MAX/Msp抄襲一曲Alva Noto(三)第二個音色
來自專欄 MAX/Msp 抗焦慮指南4 人贊了文章
第二個音色還是FM合成,其實諧波看起來更像我們現在用的參數,音高在聽感上和上一軌比大概高半音,那麼參數不用動多少。要知道在聲音合成裡邊參數如果都比較大的話,動小數點後十幾位數都可能出現兩個很難避免的問題:1.音高不對(如果還有的話,汗.jpg);2.音色差別極大。但現在我們不面臨這個問題,所以我以這一曲舉例是經過了思索的··· ···
看看這一軌的頻譜,在曲子最後有比較清楚的:
前邊那幾聲是剛才我們合成的音色,後面大半(請忽略豎著的線條,那是另一軌)是現在要合成的,是不是更像剛才參數出來的樣子?那就簡單了,只需要動一點點載波或者諧波,試試。然後時間呢?
剛好是個100毫秒的波動,另外和剛才一軌不一樣的是,它的ADSR是線性起落首尾相連的,那麼做時間的辦法就有點不一樣了。結果如下邊,就不再一個一個截圖了,太慢,這一軌大概是這樣:
除了FM上邊的參數改了一點點外,其他地方動了的都用橘色標明了。cross~這個object很簡單,就是濾波器,從它的右輸出出來,就是高通,只有高於500Hz的聲音可以通過。因為有一個很可疑的極低諧波雖然聽不見但是要參與到總的振幅裡邊去,怕呲,把它過濾了。
改動其實主要是這裡:
metro和toggle配合每50毫秒給一次下邊的message box和line~。line~是做信號線性變化的,至於怎麼變是上邊這個message給它說的,$1是可變引數,就是說上邊toggle發出的0和1會替換這個$1,後面的50指這次線性變化用時50毫秒。那麼它倆給*~發出的信號就是,每50毫秒音量從0到1,接著又從1到0,往複循環直到電腦沒電。還有就是它:
delay~是信號延遲用的,這裡的信號就是聲音。44100指的是需求的最大儲存空間,你可以理解為這個delay~最長只能延遲這麼多,而2205呢,是實際上我讓它延遲的時間,但是這裡的2205是指2205個採樣點/sample,換算出來就是50毫秒(具體換算方法可以看看mstosamps~)。因為我們看noto原版右聲道相比左邊聲音是延遲了50毫秒的。
現在對比一下,左邊noto,右邊是我們現在的:
問題還是頻率諧波的振幅有偏差,不過還是不管了··· ···整體最後聽起來不舒服再說。這一軌還有一個大的包絡沒有做,就是每7秒鐘(7000毫秒)它會突然出現再線性變小到0. 。那就再加一個line~(黃色部分),讓這一軌每7000毫秒來一個耗時5500毫秒的線性振幅,line~上頭這個message裡邊的內容表示:信號從1.到0.用5500毫秒,也就是說下次被觸發的時候是從0.突然跳到1.開始減弱的,也就順便產生那個破的噠音了。另外我給兩軌聲音都加了一個正弦波(圖中綠色部分),聽起來會更接近一些,現在整個patcher長這樣(之前的一軌聲音也加了一個cross~,但是引數用的30,這個很微妙,會影響「噠」的質感):
頻譜長這樣:
原版這樣:
依舊還是諧波的問題,沒有這麼豐富,聽起來質感會不一樣,noto更纖細。
從patcher截圖來看,現在佔了屏幕很大部分了,必須要整理,不然沒辦法寫下一軌。
那就是打包。在MAX里就是在patcher裡邊建子patcher,有點類似代碼裡邊的method。先把第一軌的這個部分選擇:
然後從頂上MAX菜單欄的edit下選擇encapsulate:
或者直接快捷鍵command+shift+e,變成這樣:
鎖定patcher之後我們雙擊這個叫p的object就能看到裡邊了。之前的內容不變,只是多了兩個這個:
它們叫outlet,通過它們子patcher裡邊的連線才能夠連接到母patcher來。這時候聲音可能已經不響了,是因為FM的參數全部歸零。這是是因為loadmess 1還沒有被激發。鎖定狀態下雙擊loadmess一切又正常了(不用擔心,下次打開程序這些還是自動的)。現在給這個叫p的子patcher起個名字,隨意,就叫它a也行。但還是有幾個命名原則:不能數字開頭,不能有空格,不能起MAX本來就有的object的名字,不要用非英文。雖然MAX不像其他代碼語言一樣,它不計較你是否違反這幾個規則,比如我來個極端的:
能犯的錯都犯全了,還是可以完全正常運行。但是最好不要有這個習慣,在代碼里這個相當於是法律,是要報錯的。而MAX裡邊更像道德、倫理,你可以沒有底線,但我們都不想成為劉鑫,我們要學雷鋒學徐洪剛。所以我改成一個有意義的好名字,一看就知道這個子patcher是幹嘛的:
駝峰命名法:除第一個單詞外其餘都首字母大寫,你也可以用下劃線,都是好人才會使的偏門心機和華麗伎倆。如法炮製第二軌,母patcher變成這樣了:
把live.gain~留在外邊是因為最後我們還要調整每一軌的音量,讓它們比例合適。之後的每一軌我們全都這樣弄。
/***分割線又來了
這裡順便說一說object的結構。如果是代碼,我們聲明的時候是這樣的:
int myNumber = 20;
int是整數類型,myNumber是你起的名稱,= 是賦值(就相當於「myNumber是多少啊?」電腦問你),20是myNumber的值(你回答它了),分號是一行結束必須加的。
那麼在MAX裡邊是這樣的:
你只要建立了這個叫做」number」的object,就表明你選擇了整數類型,如果進入的是小數點的數它都要去掉小數點之後的數值來處理,不是四捨五入,是直接不要了。這種偏差會導致結果很糟糕,所以要謹慎。開始的時候這是個常犯的錯誤。而loadmess就相當於給這個方塊賦值。那麼名稱呢?不用起,MAX在後台幫你起好了。
那麼現在看子p這個object的結構:
p clickinSine,p是子patcher(sub patcher)的簡稱,也就是這個object的名稱(或者這裡認做功能/方法),clickinSine是你給這個功能起的名字(等同於剛才的myNumber),也就是這個子patcher的名字。
我覺得說半天更暈··· ···
不如一句話:這個階段給子patcher起名字僅僅為了你能知道它的大致作用,不然過了三個星期看見patcher裡邊的7、8個p暈了(程序員問:那寫注釋呢?回答:那幹嘛不就起個名字?)。
以後分割線的內容就忽略吧,有任何問題右鍵點你要查看的object,點help,有非常詳盡的文檔。
分割結束吧***/
現在已經有兩軌聲音,在合成下一軌之前,先加一個實用技能。就是我們在編輯patcher過程中,需要不停的開關喇叭,但每次手動去點擊它十分煩人,有沒有快捷鍵呢?有,自己做一個,在MAX里,沒有實現不了的音視頻想法和效果,只是有一些需要DIY。雖然麻煩一點點,但是所有功能都是你自己定製的,很有親切感,而且不會讓不需要的功能佔用多餘的資源。像在音樂編輯軟體里,即使這一音軌你永遠不會動pan,這些模塊/組建/圖標總是還會在那裡戳著,佔用著屏幕空間甚至內存。我習慣用空白鍵來控制開關,那麼寫成這樣就ok了(無論你把它放在patcher或是子patcher的任何地方):
key是按鍵,就是說你只要點擊鍵盤上的任意鍵,就會出一個數字,這是「美國信息交換標準代碼」(ASCII)。每個鍵對應一個數字,空白鍵是32,esc是27,0是48,etc。我們這裡用的是空白鍵,其他鍵不會起任何作用,所以下邊接一個sel,也就是select的縮寫,32是它的引數(argument),意思是它現在偵測從它左輸入進來的數字,如果進入的是32,那麼它的左輸出會發出一個bang,如果不是32,什麼也不發送。所以當按一次空白鍵的時候sel 32會發出bang給下邊這個圖形界面,它叫做gswitch2,當它的左輸入收到bang就會切換輸出口,將從右輸入進來的信息從相應的輸出發送出去。聽起來有點抽象,我把這裡改成這樣,自己點一下空白鍵看起來就很直白了:
比剛才多出來的那些方塊和圈圈都只是為了展示信息來龍去脈用的。gswitch2下邊分別接了兩個message。到這裡還會有人搞混object和message嗎?再看看這張圖,注意一下長相:
在message里,「;」代表給特定對象說話(如果不是特定對象,不用分號),而在這裡特定的對象就是dsp,digital signal processing的簡稱(數字信號處理)。在Msp里信號就是聲音,只是聲音是對耳朵而言的,但在計算機里的處理過程中是被當作(持續流動的)信號的。後邊的「start」和「stop」就是要讓dsp開關聲音。其實這種簡單思路可以反映出自己編寫工具/編程的好處,達到目的非常精準和高效,沒有廢話。想想之前的FM,非常基礎的幾個object就實現了,比軟體裡邊UI化的模塊簡潔很多,尤其是一些功能掛在那裡也很少用。另一個好處是,所有東西是你一手建立的,任何問題都可以被解決。現實生活里有的事情的確很讓人煩,比如在地鐵刷個卡非得用現金買,你猜不出這一屋十幾個人誰最看不慣你,右下腹的疼痛是不是惡性腫瘤,到了最後的時刻應該相信中醫還是西醫?還是說現在就應該看心理醫生了?這類似的一堆事情是永遠弄不明白的··· ···但是當你回到屏幕前,又牢牢掌握了世界的運作,一切不便都有更優的解法,沒有什麼神秘的暗流,因為規則都是你寫的,不願在意的事情,就根本不會去創造它··· ···說起來,這是要用計算機來逃避現實還是改變現實的問題。
待個續··· ···
推薦閱讀:
TAG:Max可視化編程語言 | 計算機音樂 | 數字媒體藝術 |