跳轉到內容

SuperCollider 中的聲音設計/吱呀作響的門

來自華夏公益教科書,開放的書籍,開放的世界

圖 32.3:木門的共振峰

[編輯 | 編輯原始碼]
(
~woodfilter = { |input|
	var freqs, rqs, output;
	// Note: these freqs are as given in the diagram:
	freqs = [62.5, 125, 250, 395, 560, 790];
	// The Q values given in the diagram (we take reciprocal, since that's what BPF unit wants)
	rqs   = 1 / [1, 1, 2, 2, 3, 3];
	// in the text, andrew says that the freqs follow these ratios, 
	// which give a very different set of freqs...:
	// freqs = 125 * [0.5, 1, 1.58, 2.24, 2.92, 2, 2.55, 3.16];
	
	//Now let's apply the parallel bandpass filters, plus mix in a bit of the original:
	output = BPF.ar(input, freqs, rqs).sum + (input*0.2);

};

// Now let's use this function in something - some dust impulses tap-tap-tapping on the door:
x = {
	Pan2.ar(~woodfilter.value(  LPF.ar(Dust.ar(10), 10000)  ))
}.play;
// Doesn't sound much like a door? Compare it to the raw tapping sound (edit the above).
)


圖 32.4:響應施加力的粘滑運動

[編輯 | 編輯原始碼]
(
~stickslip = { |force|
	var inMotion, slipEvents, forceBuildup, evtAmp, evtDecayTime, evts;
	force = force.lag(0.1); // smoothing to get rid of volatile control changes
	
	inMotion = force > 0.1; // static friction: nothing at all below a certain force
	
	// slip events are generated at random with freqency proportional to force.
	// I originally used Dust to generate random events at a defined frequency, but
	// that lacks the slight "pitched" sound of the creaky door. Here we use Impulse
	// to generate a frequency, but we add some noise to its frequency to try and 
	// avoid it getting too perfectly regular.
	slipEvents = inMotion * Impulse.ar(force.linlin(0.1, 1, 1, 1/0.003) * LFDNoise1.ar(50).squared.linexp(-1,1, 0.5, 2).poll);
	
	forceBuildup = Phasor.ar(slipEvents, 10 * SampleDur.ir, 0, inf).min(1);
	
	// Whenever a slip event happens we use Latch to capture the amount of
	// force that had built up.
	evtAmp = Latch.ar(Delay1.ar(forceBuildup.sqrt), slipEvents);
	evtDecayTime = evtAmp.sqrt;
	// The book applies square-root functions to shape the dynamic range of the events.
	// Remember that square-root is computationally intensive, so for efficient 
	// generation we might want to change it to (e.g.) a pre-calculated envelope.
	
	// Now we generate the events
	evts = EnvGen.ar(Env.perc(0.001, 1), slipEvents, evtAmp, 0, evtDecayTime * 0.01);
};
// Let's plot 4 seconds worth, with steadily increasing force.
// Events should appear more frequent but less violent as the plot progresses.
{~stickslip.value(Line.kr(0,1,4))}.plot(4);
)

圖 32.5:模擬矩形門框的平行延遲

[編輯 | 編輯原始碼]
(
~squarepanel = { |input|
	var times, filt;
	// times in milliseconds, converted to seconds:
	times = [4.52, 5.06, 6.27, 8, 5.48, 7.14, 10.12, 16] * 0.001;
	filt = DelayC.ar(input, times, times).mean;
	filt = HPF.ar(filt, 125);
	filt * 4
};
)

圖 32.6:將所有內容整合在一起

[編輯 | 編輯原始碼]

以下內容結合了本頁之前定義的函式,以建立一個 你可以自己推動的門!

在執行此程式碼之前,將滑鼠移到螢幕左側。然後將滑鼠移動到右側和左側,以控制門上的力。

x = {~squarepanel.value(~woodfilter.value(~stickslip.value(MouseX.kr(0,1))))}.play
華夏公益教科書