樂器製作上,一般的鼓面通常就是一塊布、皮的材質繃緊之後就可以敲擊產生聲音。例如最常見的 Rock Drum Set 當中,**大鼓(Kick Drum)和筒鼓(Tom-Tom)**都是這樣的結構。因為震動的結構相當單純,敲擊產生的聲音頻譜也幾乎就不外乎幾個淡淡的泛音,而不會有太多的高頻。若是張力相同,小張一點的鼓面聲音就會較高。若是鼓面固定,張力越大聲音又會越高。
底下是一個簡單的 codepen,可以聽聽看他們的聲音。
上面的原理,也是為什麼我在kick 合成實驗室裡面合成大鼓的聲音時候,只需要用一個Tone.Oscillator
當作 source 就可以製造出類似的效果。也可以很簡單的推想:想要合成那種演唱會現場的一排 Tom-Tom,只要改變之前大鼓設計裡面的參數。
像是 attack 短一點、聲音低沈一點就可以製造比較鬆的鼓面的感覺。像是我設計成 class 的結構,就方便之後丟參數去生成一整組的 Drum Kit。
而在 hihat 的設計上,前幾篇中講過了 noise 的頻譜分析與其金屬質感。
若是要將上述這兩個互相比較的話,
可以說金屬質感的聲音:
鼓皮、鼓面的聲音:
為什麼要再強調一次各種鼓材質上面的差異呢?因為小鼓是一個集兩種狀態的複合體!融合啦!
小鼓在英文裡面叫作snare drum。為什麼呢?snare 許多意義當中,一個就是專指小鼓當中放的響弦。什麼?那三小?小鼓的設計原本最原始的使用場景是在站場上,而單純鼓面的聲音雖然渾厚,但因為泛音不足所以缺乏高頻的色彩。當時就發現假如在鼓面裡面加入金屬片,敲擊時同時觸發兩種聲音結構,就可以保有原本低頻的音調與金屬的高頻色彩。
慢慢演化到現在,小鼓的設計裡面響弦已經特化成非常有趣的結構:
而現代小鼓還有個功能,響弦也用一個鈕扣可以控制是否貼緊鼓面,而產生不同種的結合感。貼緊時有機槍的那種衝擊聲,放開則有 Tom-Tom 較低頻的震動。
前面講了這麼多,其實故事是這樣的。我之前想要自己合成 snare 的聲音,發現 Tone.js 並沒有一個已經做好的 snare。而找其他人的作品的時候,要嘛就是直接用 sample,或是只用 noise 的質感做小鼓(把 hihat 調一調)。但是我覺得那樣的聲音並不夠,應該不是這樣才對。
最後我看了這個音樂製作的 tutorial,發現這個比較接近我想要的質感。於是乎,把他用的聲音架構轉化到 Tone.js 裡面去實現,慢慢就體會到上面講述的複合質感的理論與實踐。
首先,如同 hihat 一樣,我們想要一個 noise 的 source。而 Tone.js 已經建好一個 instrument 叫做Tone.NoiseSynth
可以直接使用。另外,根據上面的理論,我想要的是 noise 的高頻金屬敲擊感,所以就加一個 high pass filter 把不要的雜亂低頻給拿掉:
const hpf = new Filter({
type: 'highpass',
frequency: 50,
}).toMaster();
const noise = new NoiseSynth({
volume: -12,
noise: {
type: 'pink',
playbackRate: 3,
},
envelope: {
attack: 0.001,
decay: 0.13,
sustain: 0,
release: 0.03,
},
}).connect(hpf);
第二,製造個如 Tom-Tom 的 Oscillator。但這次跟大鼓不太一樣,我想要設計一點豐富的低頻,所以用多個 Oscillator 去同時發出聲音。在 Tone.js 裡面,已經有設計好的Tone.PolySynth
可以用。與上面的原理一樣,這邊我要取的是鼓皮低頻的震動,所以加上一個 low pass filter 把高頻給清掉拿掉。如此一來,兩邊的聲音就比較不會打架了:
const lpf = new Filter({
type: 'lowpass',
frequency: 11000,
}).toMaster();
const poly = new PolySynth(6, Synth, {
volume: -10,
oscillator: {
partials: [0, 2, 3, 4],
},
envelope: {
attack: 0.001,
decay: 0.17,
sustain: 0,
release: 0.05,
},
}).connect(lpf);
之前都觸發鼓都是單次的triggerAttackRelease
或是triggerAttack
,但這樣的使用情境很有限。很多時候我們需要它自動在背景跑著某種 pattern,讓手手可以空下來去調整一些現場想要的參數感。所以這裡使用Tone.Part
來製造這樣的效果。先看看使用的過程,敲擊的實作其實就是一個 callback 裡面去呼叫個別 source 的 trigger:
...
// 敲擊後的頻率變化的曲線設定
const ratio = 11;
const attack = 0.0;
const decay = 0.04;
const part = new Part(
// 設定拍點呼叫的 callback,拍點是下一個參數定義
(time) => {
poly.voices.forEach((v, i) => {
const e = v.envelope;
// 敲擊鼓皮
e.triggerAttackRelease('16n', time);
const f = v.oscillator.frequency;
// 敲擊瞬間,鼓皮震動頻率馬上跳到 Frequency(notes[i]) * ratio
f.setValueAtTime(Frequency(notes[i]) * ratio, time + attack);
// 並設定敲擊後 decay 秒,震動頻率就會回到 notes[i]
f.exponentialRampToValueAtTime(notes[i], time + decay);
});
// 敲擊金屬
noise.triggerAttackRelease('16n', time);
},
// 設定每個小節 1, 3 拍會敲擊(呼叫 callback)
['0:1', '0:3'],
).start();
...
若有不清楚地註解,可以直接參考 Tone.js 的 docs。而關於拍點的設定為什麼會有['0:1', '0:3']
這樣的格式,可以參考 Tone.js Wiki: Time,裡面有比較詳盡的介紹,像是'16n'
, '18n'
, '2m'
, '1:2'
, '+0.5'
等等各有不同的意義。
振盪器派對!演算 の 鼓組!終於可以告一個段落了!我們做了大鼓、hihat、小鼓,一個一個手工車床、上皮、鎖緊、敲擊、快感!
太感動了,下一篇終於可以把vsynth—3002接上參數,震動派對現場。
關於作者
Vibert Thio
致力於將對於技術的深度研究轉化為新型態藝術創作的能量,並思考技術的拓展/侷限與其對於藝術論述/呈現的影響。專長為數位藝術創作、音像程式設計、互動設計,喜愛即時運算的臨場感與不可預測。