Example 4

From CSWiki
Jump to: navigation, search

This is an example from the PMOsc help page in SC3: every two seconds, an FM sound fades in and out over 9 seconds, somewhere in the stereo field, with an index growing from 0 to somewhere as high as 12 (and any float in between). The result is a nice swarming drone of varying FM sounds.

The ChucK version runs at a significantly higher CPU cost, so you might get jittering if you have too many other things running. DT: however, if the FM synthesis is implemented using 2 => c.sync, as in Example 3, then this should run pretty efficiently, and certainly much more efficiently than here; any loop that does much of anything with 1::samp => now is going to be inefficient.

the SuperCollider code

Routine({
	loop{
		{
			LinPan2.ar(
				EnvGen.ar(Env.linen(2, 5, 2), doneAction: 2)
				*
				PMOsc.ar(2000.rand, 800.rand, Line.kr(0.0, 12.0.rand, 9), 0, 0.1), 
				1.0.rand2
			)
		}.play;
		2.wait;
	};         
}).play;

the ChucK version

function void makeFMsound(float maxAmp)
{
	SinOsc c => Gain amp => Pan2 panner; // carrier
	panner.left => dac.left;
	panner.right => dac.right;
	SinOsc m => blackhole; // modulator
	Std.rand2f(-1.0,1.0) => panner.pan;
 	Std.rand2f(20.0,2000.0) => float cf => c.freq;
	Std.rand2f(0.0,800.0) => float mf => m.freq;

 	Phasor ampPhasor => CurveTable ampEnv => blackhole;
	[
	0.0, 0.0, 0.0,
	2.0, maxAmp, 0.0,
	7.0, maxAmp, 0.0,
	9.0, 0.0
	] @=> float times[] => ampEnv.coefs;
	1.0/9.0 => ampPhasor.freq;
	
	Phasor indexPhasor => CurveTable indexEnv => blackhole;
	Std.rand2f(0.0,12.0) => float maxIndex;	
	[
	0.0, 0.0, 0.0,
	9.0, maxIndex
	] @=> float indexTimes[] => indexEnv.coefs;
	1.0/9.0 => indexPhasor.freq;

	9 * 44100 => int totalsamples;
	for (0 => int i; i < totalsamples; i++)
	{
		cf + (indexEnv.last() * mf * m.last()) => c.freq;
		ampEnv.last() => amp.gain;
		1::samp => now;
	};
};

while (true)
{
	spork ~ makeFMsound(0.1);
	2::second => now;
};