SoundEngraver

NodeProxy

Jun 5th, 2024 (edited)
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ////////////////////// NodeProxy //////////////////////
  2.  
  3. // The following code may be suitable for live coding.
  4.  
  5. // NodeProxy is a reference on a server. A proxy is a placeholder for something. A node proxy is a placeholder for something playing on a server. That something is typically a synth or an event stream that creates synths.
  6.  
  7. // NodeProxy objects can be replaced, revised, and recombined while they play.
  8. // These objects can be used to build a larger structure and can be modified later on.
  9.  
  10. // NodeProxy is used within ProxySpace. NodeProxy is a superclass of Ndef.
  11. // Important: NodeProxy plays on a private bus. For audible output, use the play and stop methods.
  12. // To free inner players, use the end method. To remove all inner settings, use the clear method.
  13.  
  14. // The following example is based on the Help page.
  15.  
  16. s.boot;
  17.  
  18. s.plotTree; // I recommend refering to this, so you can see the Server's internal dialogue.
  19. s.meter; // A good reference for audio output and, more importantly, volume.
  20. s.scope; // I personally like to keep this visible.
  21.  
  22.  
  23. s.quit;
  24.  
  25. a = NodeProxy.new.play; // Play to hardware output.
  26. a.fadeTime = 2; // FadeTime specifies crossfade. This line evaluates a crossfade of 2 seconds.
  27.  
  28. // Set the source.
  29.  
  30. a.source = {SinOsc.ar([350, 351.3], 0, 0.1)};
  31. a.source = {Pulse.ar([350, 351.3] / 4, 0.4) * 0.05};
  32. a.source = Pbind(\dur, 0.03, \freq, Pbrown(0, 1, 0.1, inf).linexp(0, 1, 200, 350));
  33.  
  34. b = NodeProxy.new;
  35. a.source = {Ringz.ar(b.ar, [220, 221.5] * 8, 0.1) * 4};
  36.  
  37. // When you evaluate this, after evaluating the new value name, "b", the a.source (in this case, the Ringz UGen, fades the previous sound by 2 seconds. Once you evaluable the b.source below, you have Ringz under an Impulse control.
  38.  
  39. b.source = {Impulse.ar([5, 7]/2, [0, 0.5], 0.05)}; // Keep this at a very low amplitude!
  40.  
  41. a.clear(3); // clear after 3 seconds
  42. b.clear(3); // this too clears after 3 seconds
  43.  
  44.  
  45.  
  46. ////////////// The following code is based on Eli Fieldsteel's tutorial, Live Coding, Part 1. //////////////
  47.  
  48. n = NodeProxy.new;
  49. n.isPlaying; // The result is false until we evaluate the play method.
  50.  
  51. n.play; // The top Group is the reference of the source. The bottom Group is the Server's audio output.
  52. n.clear; // This is effectively a hard stop. It clears everything. Evaluate the play method, for when you want audio output.
  53.  
  54. // Let's put in a source, which is designated for the top Group.
  55.  
  56. n.source; // Result is "nil," if you've previously cleared the source.
  57. n.play;
  58.  
  59. n.source = {PinkNoise.ar(0.1!2)}; // The current audio source is pink noise.
  60. n.source = {SinOsc.ar([220, 222], mul: 0.1) * LFPulse.kr([4, 5])}; // Instantly change the audio source.
  61.  
  62. // It's up to you, if you prefer to write out consecutive sources and run them one at a time.
  63. // For live coding, I generally see people change the source in the same line of code.
  64.  
  65. n.clear(4); // The clear method includes a fadeTime value. Here, it's a fade time of 4 seconds.
  66.  
  67. n.play;
  68. n.source = {PinkNoise.ar(0.1!2) * LFTri.kr(4)};
  69.  
  70. n.stop; // Not the most elegant way of releasing the synth. But you have this as an option.
  71.  
  72. n.play;
  73. n.clear(4); // This has a release time of 4 seconds.
  74.  
  75. // fadeTime
  76.  
  77. n.play;
  78. n.source_({LPF.ar(Saw.ar([80, 82], mul: 0.05), 1000)});
  79.  
  80. n.fadeTime; // Default fade time is 0.02 seconds.
  81. n.fadeTime_(3); // This acts as a crossfade between sources (that you change in real time).
  82.  
  83. n.fadeTime; // See the result now in the Post Window.
  84.  
  85. // For example, change the different paramters of the source below. Like the Saw's frequency values, or the Lowpass filter's cutoff value.
  86.  
  87. n.source_({LPF.ar(Saw.ar([80, 81], mul: 0.05), 2000)});
  88.  
  89. n.clear(8); // Clear the source with a release time of 8 seconds.
  90.  
  91. // Just for musicality, let's use the midiratio method to change the Sawtooth wave in semitones.
  92.  
  93. n.play;
  94. n.source_({LPF.ar(Saw.ar([80, 81] * 0.midiratio, mul: 0.05), 2000)});
  95.  
  96. n.fadeTime_(2); // Note, this isn't the same as the clear method; it's a crossfade between sources playing.
  97. n.clear(2);
  98.  
  99. // If you don't want to clear a source, but want to momentarily silence it, the following code works:
  100.  
  101. n.source_({LPF.ar(Saw.ar([80, 81] * -5.midiratio, mul: 0.05), 1200)});
  102. n.play;
  103.  
  104. n.source_({ });
  105. n.clear(1);
  106.  
  107. // Think of the play and stop methods as a hard on and off switch.
  108.  
  109. n.play;
  110. n.stop; // You'll see the Server removes the Group designated for audio output.
  111.  
  112. // Evaluating "n.play" again with return to the last source value and play it.  We also have the following.
  113.  
  114. n.monitor.fadeTime_(5); // Think of this as a fade in and out feature. Go between stop and play.
  115. // This monitor method dictates the audio output Group (bottom Group).
  116.  
  117. n.source_({LPF.ar(Saw.ar([80, 81] * -5.midiratio, mul: 0.05), 1200)});
  118.  
  119. n.stop;
  120. n.play; // Evaluating this will instantaneously provide the audio output Group.
  121.  
  122. // Note the difference between this and the NodeProxy's fade time.
  123.  
  124. n.fadeTime_(5);
  125. n.release;
  126. n.send; // This reinstantiates the source object (in the top Group).
  127.  
  128. // And "send" will return a random value within the Group. Let's try this with random semitones using the midiratio values method.
  129.  
  130. n.source_({LPF.ar(Saw.ar([80, 81] * Rand(-5.0, 5.0).midiratio, mul: 0.05), 1200)});
  131.  
  132. n.send; // Send can also reevaluate itself; You don't need to release it.
  133. n.release; // The realease time is whatever the fadeTime value is.
  134.  
  135.  
  136. // Make changes using the pause and resume methods. That is, if you don't want to hear the output as you make changes.
  137.  
  138. n.pause;
  139. n.resume;
  140.  
  141. n.stop;
  142.  
  143. // Run more than one instance of NodeProxy.
  144.  
  145. m = NodeProxy.new; // Note the new global variable letter.
  146.  
  147.  
  148. m.fadeTime_(8);
  149. m.play;
  150.  
  151. m.source_({ Dust.ar(8!2, mul: 0.3) });
  152. m.source_({ Impulse.ar([8, 10], mul: 0.3) * SinOsc.kr(0.2, 3pi/2).exprange(0.25, 1)});
  153.  
  154. m.clear(4);
  155.  
  156. // To clear both NodeProxy instances, you can...
  157.  
  158. (
  159. m.clear;
  160. n.clear;
  161. )
  162.  
  163. // But what if you accidentally designate two sources to the same variable name (e.g. global variable, n)?
  164. // Answer: The most recent instance overwrites the first one.
  165.  
  166. // Ndef is a more elegant way to do this.
  167.  
  168.  
  169. Ndef(\n).play;
  170. Ndef(\n).fadeTime_(2);
  171. Ndef(\n, { Dust.ar(8!2, mul: 0.3) }); // Now, you don't need to use the source method.
  172.  
  173. Ndef(\n).release;
Add Comment
Please, Sign In to add comment