Advertisement
SoundEngraver

FM Synthesis | FM Basics (Part 4)

Feb 28th, 2023 (edited)
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////// FM SYNTHESIS | FM Basics (Part 4) ///////////////////////
  2.  
  3. s.boot;
  4.  
  5. // Run these methods below for visual cues.
  6.  
  7. s.meter;
  8. s.scope;
  9. s.plotTree;
  10.  
  11. // I use the following only when necessary.
  12.  
  13. s.reboot;
  14. s.quit;
  15.  
  16.  
  17. // In Part 2, I cover Amplitude Modulation (AM). In Part 3, I continue with FM.
  18. // Here, in Part 4, we cover more divergent uses for FM.
  19.  
  20. ////////////////// Things To Know Before Running Code //////////////////
  21.  
  22. /*
  23.  
  24. All my original SC documents are in the "dracula" color.
  25. To find or change this, go To SuperCollider ––> Preferences ––> Editor ––> Font & Colors.
  26. ––> Select under Color, dracula.
  27.  
  28. Arguments in Synths are represented with a backslash, "\", in green under the "dracula" color font. Values presented with these arguments can be changed. Only remember to NEVER cross 0, when using an exponential method like "exprand."
  29.  
  30. Arguments also precede a colon ":", as seen in a list of a UGen following a variable, "var."
  31. Example: sig = PlayBuf.ar(2, buf, rate, startPos: spos);
  32.  
  33. Argument and variable names can be changed to your liking.
  34.  
  35. Please be careful with volume output. Always have SuperCollider run through headphones. If you're unsure what the output will be, keep headphones away, with your main volume all the way down. Check your level meter and Stethoscope for visual cues. If everything looks safe (e.g. level meter is NOT in the red), proceed.
  36.  
  37. You can always execute a hard stop with Command Period.
  38.  
  39. */
  40.  
  41. // SynthDefs
  42.  
  43. Env([0, 1, 0], [0.1, 3], [1, -5]).plot; // Envelope shape to reference.
  44. // First array, [0, 1, 0], are levels.
  45. // Second array, [0.1, 3], are times traversing between levels.
  46. // Third array, [1, -5], are curve values.
  47.  
  48.  
  49. // What's happening here? (Hint: We've covered this line of code in FM Basics, Part 1.)
  50.  
  51. {LFPar.ar(LFPar.kr(LFPar.kr(0.2, 0, 8, 10), 0, 200, 800), 0, 0.1)!2}.play;
  52. // Execute a hard stop with Command Period.
  53.  
  54.  
  55. // You have two Parabolic Oscillators working as controls for a Parabolic signal.
  56. // {LFPar.ar(), 0, 0.1)}, the outermost part of the Function, is the signal.
  57. // I keep the innermost LFPar's at a control rate ("LFPar.kr"), and the main signal at audio rate ("LFPar.ar"). If I remember correctly, this is less CPU expensive than applying audio rate to every control UGen.
  58.  
  59. // The two innermost oscillators perform the following:
  60.  
  61. // Sine tone at 800Hz travels to 1000Hz, then to 600Hz, in the course of 5 seconds.
  62. // Simultaneously, you have a modulatory fluctuation from 10 to 2 cycles every 5 seconds.
  63. // 10-8 = 2. The integer 8 determines the lowest cycle value of the innermost parabolic oscillator.
  64.  
  65.  
  66.  
  67. // Integrate this into a SynthDef. (The code below isn't covered in Part 1.)
  68.  
  69. (
  70. SynthDef.new(\parSine, {
  71.     arg out=0;
  72.     var sig;
  73.     sig = LFPar.ar(LFPar.kr(LFPar.kr(0.25, 0, 8, 10), 0, 200, 800), 0, 0.1);
  74.     sig = sig!2;
  75.     Out.ar(out, sig);
  76. }).add;
  77. )
  78.  
  79. Synth(\parSine);
  80. // Execute hard stop with Command Period. (You may need to reevaluate the SynthDef.)
  81.  
  82. // Add an Envelope
  83.  
  84. Env([0, 1, 0], [0.1, 8], [1, -5]).plot;
  85.  
  86. (
  87. SynthDef.new(\parSine1, {
  88.     arg atk=0.1, rel=8, c1=1, c2=(-5), out=0;
  89.     var sig, par, env;
  90.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  91.     par = LFPar.ar(LFPar.kr(LFPar.kr(0.25, 0, 8, 10), 0, 200, 800), 0, 0.1);
  92.     sig = par * env;
  93.     sig = sig!2;
  94.     Out.ar(out, sig);
  95. }).add;
  96. )
  97.  
  98. Synth(\parSine1);
  99.  
  100.  
  101. // Add argument names to change argument values in real time.
  102.  
  103. (
  104. SynthDef.new(\parSine1, {
  105.     arg atk=0.1, rel=8, c1=1, c2=(-5),
  106.     parCtrl=0.25, parMin=8, parMax=10, addCtrl=200, parFreq=800,
  107.     parAmp=0.1, out=0;
  108.     var sig, par, env;
  109.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  110.     par = LFPar.ar(
  111.         LFPar.kr(
  112.             LFPar.kr(parCtrl, 0, parMin, parMax), 0, addCtrl, parFreq),
  113.         0,
  114.         parAmp);
  115.     sig = par * env;
  116.     sig = sig!2;
  117.     Out.ar(out, sig);
  118. }).add;
  119. )
  120.  
  121. Synth(\parSine1);
  122.  
  123. // Don't run this too many times at once.
  124.  
  125. (
  126. Synth(\parSine1, [
  127.     \atk, rrand(0.1, 1),
  128.     \rel, rrand(2, 8),
  129.     \c1, rrand(1, 4),
  130.     \c2, rrand(-1, -5),
  131.     \parCtrl, rrand(0.125, 4),
  132.     \parMin, rrand(3, 8),
  133.     \parMax, rrand(9, 10),
  134.     \addCtrl, rrand(20, 200),
  135.     \parFreq, rrand(400, 1000),
  136.     \parAmp, rrand(0.1, 0.3) // I'd keep the amp down for these.
  137. ]);
  138. )
  139.  
  140.  
  141. // Slower Motion
  142.  
  143. {LFPar.ar(LFPar.kr(0.2, 0, 400, 800), 0, 0.1)!2}.play;
  144. // Execute hard stop with Command Period.
  145.  
  146.  
  147. // SynthDef Version
  148.  
  149. (
  150. SynthDef.new(\slowSine, {
  151.     arg out=0;
  152.     var sig;
  153.     sig = LFPar.ar(LFPar.kr(0.2, 0, 400, 800), 0, 0.1);
  154.     sig = sig!2;
  155.     Out.ar(out, sig);
  156. }).add;
  157. )
  158.  
  159. Synth(\slowSine);
  160.  
  161.  
  162. // Add an Envelope
  163.  
  164. (
  165. SynthDef.new(\slowSine, {
  166.     arg atk=0.1, rel=8, c1=1, c2=(-5), out=0;
  167.     var sig, par, env;
  168.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  169.     par = LFPar.ar(LFPar.kr(0.2, 0, 400, 800), 0, 0.1);
  170.     sig = par * env;
  171.     sig = sig!2;
  172.     Out.ar(out, sig);
  173. }).add;
  174. )
  175.  
  176. Synth(\slowSine); // Notice the softer attack (atk value: 0.1).
  177.  
  178.  
  179. // Add Arguments Names
  180.  
  181. (
  182. SynthDef.new(\mySine, {
  183.     arg atk=0.1, rel=8, c1=1, c2=(-5),
  184.     parCtrl=0.2, parMin=400, parMax=800, parAmp=0.1, out=0;
  185.     var sig, par, env;
  186.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  187.     par = LFPar.ar(LFPar.kr(parCtrl, 0, parMin, parMax), 0, parAmp);
  188.     sig = par * env;
  189.     sig = sig!2;
  190.     Out.ar(out, sig);
  191. }).add;
  192. )
  193.  
  194. Synth(\mySine);
  195.  
  196. // Don't run this too many times at once.
  197.  
  198. (
  199. Synth(\mySine, [
  200.     \atk, rrand(0.1, 1),
  201.     \rel, rrand(4, 12),
  202.     \c1, rrand(1, 4),
  203.     \c2, rrand(-1, -5),
  204.     \parCtrl, rrand(0.125, 8),
  205.     \parMin, rrand(20, 200),
  206.     \parMax, rrand(400, 2000),
  207.     \parFreq, rrand(0.125, 8),
  208.     \parAmp, rrand(0.05, 0.1) // I'd keep the amp down for these.
  209. ]);
  210. )
Tags: fm synthesis
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement