Advertisement
SoundEngraver

FM Synthesis | FM Basics (Part 3)

Feb 25th, 2023 (edited)
408
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////// FM SYNTHESIS | FM Basics (Part 3) ///////////////////////
  2.  
  3.  
  4. s.boot;
  5.  
  6. // Run these methods below for visual cues.
  7.  
  8. s.meter;
  9. s.scope;
  10. s.plotTree;
  11.  
  12. // I use the following only when necessary.
  13.  
  14. s.reboot;
  15. s.quit;
  16.  
  17.  
  18. // In Part 2, I cover Amplitude Modulation (AM). Let's move on to Frequency Modulation (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. {SinOsc.ar(SinOsc.kr(1, 0, 400, 800), 0, 0.25)}.plot;
  50.  
  51. // Let's put this in a SynthDef with designated names for the arguments.
  52.  
  53. (
  54. SynthDef.new(\sinSine, {
  55.     arg sinCtrl=1, mulCtrl=80, addCtrl=800, ampCtrl=0.25, out=0;
  56.     var sig;
  57.     sig = SinOsc.ar(SinOsc.kr(sinCtrl, 0, mulCtrl, addCtrl), 0, ampCtrl);
  58.     // With default values, the line of code reads as: sig = SinOsc.ar(SinOsc.kr(1, 0, 80, 800), 0.25).
  59.     // FM occurs with the signal traveling up from 800Hz to 880Hz, then down to 720Hz, in the course of 1 second, with the amplitude of 0.25. Contrast this with Part 2, where the given control values produce AM.
  60.     sig = sig!2;
  61.     Out.ar(out, sig);
  62. }).add;
  63. )
  64.  
  65. Synth(\sinSine);
  66. // Execute hard stop with Command Period. (You may need to reevaluate the SynthDef.)
  67.  
  68. Synth(\sinSine, [\sinCtrl, rrand(1, 10)]); // Don't run this more than once at a time.
  69. // This causes the signal to traverse through default values between 1 and 10 times per second.
  70.  
  71.  
  72.  
  73. // Let's add an Envelope. Please note, it's easy to confuse the Release of an Envelope with Amplitude Modulation, because the sound is decreasing to nothing over the length of the Release.
  74.  
  75. Env([0, 1, 0], [0.1, 8], [1, -5]).plot;
  76.  
  77. (
  78. SynthDef.new(\sinSine1, {
  79.     arg atk=0.1, rel=8, c1=1, c2=(-5),
  80.     sinCtrl=1, mulCtrl=80, addCtrl=800, ampCtrl=0.25, out=0;
  81.     var sig, env;
  82.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  83.     sig = SinOsc.ar(SinOsc.kr(sinCtrl, 0, mulCtrl, addCtrl), 0, ampCtrl);
  84.     sig = sig * env;
  85.     sig = sig!2;
  86.     Out.ar(out, sig);
  87. }).add;
  88. )
  89.  
  90.  
  91. Synth(\sinSine1);
  92.  
  93. // Because the Envelope releases the Synth, you may evaluate a few times or more, simultaneously.
  94. // Just be careful with volume.
  95.  
  96. (
  97. Synth(\sinSine1, [
  98.     \sinCtrl, rrand(1, 10),
  99.     \mulCtrl, rrand(20, 200),
  100.     \addCtrl, rrand(400, 1000),
  101.     \ampCtrl, rrand(0.1, 0.35),
  102.     \rel, rrand(2, 8)
  103. ]);
  104. )
  105.  
  106.  
  107. {SinOsc.ar(XLine.kr(200, 2000, 8), 0, 0.1)}.play; // mono;
  108. {SinOsc.ar(XLine.kr(200, 2000, 8), 0, 0.1)!2}.play; // stereo
  109.  
  110.  
  111. // Above is a sine tone ascending from 200 to 2000Hz in the course of 8 seconds.
  112.  
  113.  
  114. // Add an oscillation control variable.
  115. // Here, 200Hz is traveling to 2000Hz in the course of 8 seconds. Simultaneously, an FM control is traversing between 1 and 8 cycles per second, in the course of 8 seconds. We have no Envelope to release the Synth.
  116.  
  117.  
  118. (
  119. SynthDef.new(\sineAscend, {
  120.     arg out=0;
  121.     var sig, line, env;
  122.     line = SinOsc.ar(XLine.kr(1, 8, 8), 0, 0.25); // mul arg functions as amplitude
  123.     sig = SinOsc.ar(XLine.kr(200, 2000, 8), 0, 0.5); // mul arg functions as amplitude
  124.     sig = sig * line;
  125.     sig = sig!2;
  126.     Out.ar(out, sig);
  127. }).add;
  128. )
  129.  
  130. Synth(\sineAscend);
  131. // Execute hard stop with Command Period. (You may need to reevaluate the SynthDef.)
  132.  
  133.  
  134. // Add Envelope
  135.  
  136. Env([0, 1, 0], [1, 8], [1, -1]).plot;
  137.  
  138.  
  139. (
  140. SynthDef.new(\sineAscend, {
  141.     arg atk=1, rel=8, c1=1, c2=(-1), out=0;
  142.     var sig, line, env;
  143.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  144.     line = SinOsc.ar(XLine.kr(1, 8, 8), 0, 0.25); // mul arg functions as amplitude
  145.     sig = SinOsc.ar(XLine.kr(200, 2000, 8), 0, 0.5); // mul arg functions as amplitude
  146.     sig = sig * line * env;
  147.     sig = sig!2;
  148.     Out.ar(out, sig);
  149. }).add;
  150. )
  151.  
  152. Synth(\sineAscend);
  153.  
  154.  
  155. (
  156. SynthDef.new(\sineDescend, {
  157.     arg atk=1, rel=8, c1=1, c2=(-1), out=0;
  158.     var sig, line, env;
  159.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  160.     line = SinOsc.ar(XLine.kr(8, 1, 8), 0, 0.25); // mul arg functions as amplitude
  161.     sig = SinOsc.ar(XLine.kr(2000, 200, 8), 0, 0.5); // mul arg functions as amplitude
  162.     sig = sig * line * env;
  163.     sig = sig!2;
  164.     Out.ar(out, sig);
  165. }).add;
  166. )
  167.  
  168. Synth(\sineDescend);
  169.  
  170.  
  171. // Add Argument Names
  172.  
  173. (
  174. SynthDef.new(\sineAscend, {
  175.     arg sineStart=1, sineEnd=10, sigStart=200, sigEnd=2000, sineDur=8, sigDur=8,
  176.     atk=1, rel=8, c1=1, c2=(-1), sineAmp=0.5, sigAmp=0.5, out=0;
  177.     var sig, sine, env;
  178.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  179.     sine = SinOsc.ar(XLine.kr(sineStart, sineEnd, sineDur), 0, sineAmp);
  180.     sig = SinOsc.ar(XLine.kr(sigStart, sigEnd, sigDur), 0, sigAmp);
  181.     sig = sig * sine * env;
  182.     sig = sig!2;
  183.     Out.ar(out, sig);
  184. }).add;
  185. )
  186.  
  187. Synth(\sineAscend);
  188.  
  189. // Don't run this too many times at once. I'd keep the amp values low when experimenting.
  190.  
  191. (
  192. Synth(\sineAscend, [
  193.     \sineStart, rrand(1, 10),
  194.     \sineEnd, rrand(10, 100),
  195.     \sigStart, rrand(100, 200),
  196.     \sigEnd, rrand(500, 2000),
  197.     \sineAmp, rrand(0.01, 0.3),
  198.     \sigAmp, rrand(0.01, 0.5),
  199.     \sineDur, rrand(4, 8),
  200.     \sigDur, rrand(4, 8),
  201.     \atk, rrand(0.1, 1),
  202.     \rel, rrand(2, 12),
  203.     \c1, rrand(1, 4),
  204.     \c2, rrand(-1, -8),
  205. ]);
  206. )
  207.  
  208. // Add Argument Names For Descension
  209. (
  210. SynthDef.new(\sineDescend, {
  211.     arg sineStart=1, sineEnd=10, sigStart=2000, sigEnd=200, sineDur=8, sigDur=8,
  212.     atk=1, rel=10, c1=1, c2=(-1), sineAmp=0.5, sigAmp=0.5, out=0;
  213.     var sig, sine, env;
  214.     env = Env([0, 1, 0], [atk, rel], [c1, c2]).kr(2);
  215.     sine = SinOsc.ar(XLine.kr(sineStart, sineEnd, sineDur), 0, sineAmp);
  216.     sig = SinOsc.ar(XLine.kr(sigStart, sigEnd, sigDur), 0, sigAmp);
  217.     sig = sig * sine * env;
  218.     sig = sig!2;
  219.     Out.ar(out, sig);
  220. }).add;
  221. )
  222.  
  223. Synth(\sineDescend);
  224.  
  225. // Don't run this too many times at once. I'd keep the amp values low when experimenting.
  226.  
  227. (
  228. Synth(\sineDescend, [
  229.     \sineStart, rrand(1, 10),
  230.     \sineEnd, rrand(10, 100),
  231.     \sigStart, rrand(1000, 5000),
  232.     \sigEnd, rrand(10, 1000),
  233.     \sineAmp, rrand(0.05, 0.3),
  234.     \sigAmp, rrand(0.1, 0.3),
  235.     \sineDur, rrand(4, 8),
  236.     \sigDur, rrand(4, 8),
  237.     \atk, rrand(0.1, 1),
  238.     \rel, rrand(2, 12),
  239.     \c1, rrand(1, 4),
  240.     \c2, rrand(-1, -8),
  241. ]);
  242. )
  243.  
  244.  
  245.  
Tags: fm synthesis
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement