«Simple FM template with additive mixing of modulators» by LFSaw

on 02 Mar'20 15:05 in fmcode forktemplate

Template to create a 2x3 FM Synth. There are two independent FM synths, of type car(mod1(mod2)). all carriers and modulators are collected together and are mixed to the output according to adLevels. This is intended to be a starting point for further exploration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
(
Ndef(\a, {
	var fundFreqs, ratios, fmLevels, adLevels, partials, snd;
	fundFreqs = [730, 150];
	ratios = [
		[1, 3, 5], // three vals
		[2, 3, 9]
	];
	fmLevels = [
		[0.5, 0.3], // interrelation between two modulators, hence 2 vals
		[0.7, 0.3]
	];
	adLevels = [
		[1, 0.2, 0.6],
		[0.9, 0.3, 0.3]
	];
	
	snd = [fundFreqs, ratios, fmLevels, adLevels].flop.collect{|v|
		var fundFreq, ratios, fmLevels, adLevels, partials, prevFMLevels;
		#fundFreq, ratios, fmLevels, adLevels = v;
		
		// create stacked modulators
		// start with innermost modulator
		ratios = ratios.reverse;
		prevFMLevels = (fmLevels ++ [1]).reverse;
		
		partials = [ratios, prevFMLevels, adLevels].flop.inject([0], {|prev, vals|
			var ratio, prevFMLevel;
			#ratio, prevFMLevel = vals;
			
			// "r: % \t l: % \t %".format(ratio, fmLevel, prev).postln;
			[SinOsc.ar((fundFreq * ratio) + (prev.first * fundFreq * prevFMLevel))] ++ prev
		});
		
		partials = partials[0..(partials.size-2)]; // now should have [car, mod1, mod2, ...]
		partials = partials * adLevels;
	};
	snd = Mix(snd.flat);
	
	snd!2
})
)

Ndef(\a).edit
raw 1139 chars (focus & ctrl+a+c to copy)
reception
comments