跳轉到內容

在 SuperCollider/Boing 中設計聲音

來自 Wikibooks,開放世界中的開放書籍

圖 33.2a:夾緊模式振動

[編輯 | 編輯原始碼]
(
~clampedmodes = { |basefreq, env|
	
	var freqs, amps;
	
	freqs = [1, 6.267, 17.55, 34.39];
	amps  = [0.5, 0.25, 0.125, 0.06125];
	
	Klank.ar(`[freqs, amps, 0.2], env, basefreq);
};

{~clampedmodes.(100, Impulse.ar(10))}.plot(1)
)

圖 33.2b:自由模式振動

[編輯 | 編輯原始碼]
(
~freemodes = { |input, basefreq=100, res=80|
	var filtfreqs;
	
	// The actual filter freqs take these harmonic relationships:
	filtfreqs = basefreq * [1, 2.7565, 5.40392, 8.93295, 13.3443, 18.6379];

	BPF.ar(input, filtfreqs, 1/res).sum * 10
};

{~freemodes.(LFSaw.ar(4))}.plot(1)
)

撥動尺子的運動

[編輯 | 編輯原始碼]

在這裡我們使用 Env 建立一個非對稱波形 - 當值低於零時,尺子會接觸到桌子,因此實際上“更短”。因此,它在較低的週期中比在較高的週期中具有更高的頻率(更短的波長)。

~rulerwave = Env([1, 0, -0.7, 0, 1], [0.3, 0.1, 0.1, 0.3], [4, -4, 4, -4]).asSignal(512).asWavetable;
~rulerwave.plot;
// Here let's plot it running at a frequency that speeds up.
// This approximates the actual trajectory of motion of the end of the ruler:
{Osc.kr(~rulerwave.as(LocalBuf), XLine.kr(50, 100, 1), mul: XLine.kr(1, 0.001, 1))}.plot(1)

// Now, every time the wave passes zero in a downwards-going direction, that represents the ruler thwacking on the table and therefore transmitting energy into the resonances.
// This code builds on the previous one to derive the thwacks - one at each downward zero crossing, with an energy proportional to the speed (==derivative of position, found using Slope)
(
{
	var motion, thwacks, isDown;
	motion = Osc.ar(~rulerwave.as(LocalBuf), XLine.kr(50, 100, 1), mul: XLine.kr(1, 0.001, 1));
	isDown = motion < 0;
	thwacks = Trig1.ar(isDown, 0) * (0-Slope.ar(motion)) * 0.01;
	thwacks = LPF.ar(thwacks, 500);
	[motion, isDown, thwacks]
}.plot(1)
)


讓我們聽聽

[編輯 | 編輯原始碼]

好的,現在我們需要從這些資料中製作聲音。如果 isDown==true,共鳴器的基頻更高,因為有效長度更短。因此,我們需要同時調製基頻並推動擊打聲穿過共鳴器。

(
{
	var motion, thwacks, isDown, basefreq;
	motion = Osc.ar(~rulerwave.as(LocalBuf), XLine.kr(10, 100, 1), mul: Line.kr(1, 0.001, 1, doneAction: 2));
	isDown = motion < 0;
	thwacks = Trig1.ar(isDown, 0) * (0-Slope.ar(motion)) * 0.01;
	thwacks = LPF.ar(thwacks, 500);
	
	basefreq = if(isDown, 289, 111);
	~freemodes.value(thwacks, basefreq, 100)
		+
	~clampedmodes.value(basefreq, thwacks);
}.play
)


// That was a model of a ruler-on-a-desk. The next one is... something else.

(
{
	var motion, thwacks, isDown, basefreq;
	motion = Osc.ar(~rulerwave.as(LocalBuf), 80, mul: Line.kr(1, 0.001, 1, doneAction: 2));
	isDown = motion < 0;
	thwacks = Trig1.ar(isDown, 0) * (0-Slope.ar(motion)) * 0.01;
	
	basefreq = if(isDown, 289, 111) * Pulse.ar(10).exprange(0.9, 1.1);
	~freemodes.value(thwacks, basefreq, 100)
		+
	~clampedmodes.value(basefreq, thwacks);
}.play
)
華夏公益教科書