Product SiteDocumentation Site

11.3.11.4. Using Busses: Control-Rate Example

The best way to understand how and when to use a bus is to see them in action.
( // execute first: prepare the server
   var busAudioSynth = 
   {
      arg bus, freqOffset = 0;
      
      Out.ar( 0, SinOsc.ar( freq:( In.kr(bus) + freqOffset ), mul:0.1 ) );
   };
   
   var busControlSynth =
   {
      arg bus, freq = 400;
      
      Out.kr( bus, SinOsc.kr( freq:1, mul:( freq/40 ), add:freq ) );
   };
   
   SynthDef( \tutorialAudioBus, busAudioSynth ).send( s );
   SynthDef( \tutorialControlBus, busControlSynth ).send( s );
   
   b = Bus.control( s );
)

( // execute second: create synths
   x = Synth.new( \tutorialControlBus, [\bus, b] ); // control synth
   y = Synth.after( x, \tutorialAudioBus, [\bus, b] ); // low audio synth
   z = Synth.after( x, \tutorialAudioBus, [\bus, b, \freqOffset, 200] ); // high audio synth
)

( // commands to free each Object
   x.free; x = nil; // control synth
   y.free; y = nil; // low audio synth
   z.free; z = nil; // high audio synth
   b.free; b = nil; // control bus
)
This example contains three stages: prepare the server, create the synths, destroy the synths. These three stages will become familiar as you program in SuperCollider, whether or not you use busses frequently. The example is fairly complicated, so the code is explained here:
  • busAudioSynth Function: Accepts two arguments, and creates an audio-rate SinOsc, routed to the left output channel. The frequency is determined by a control-rate bus given as an argument, and optionally with an offset that can be supplied as an argument.
  • busControlSynth Function: Accepts two arguments, and creates a control-rate SinOsc, routed to the bus given as an argument. Can also be given a frequency; the value produced by the synth is intended to be used to control pitch. The centre pitch of the oscillation is freq, and the range of oscillation is one-twentieth the size of freq (one-fourtieth both higher and lower than freq).
  • SynthDef: These commands are straight-forward. They send the synthesis definitions to the server.
  • b = Bus.control( s ); : This should also be straight-forward. A single-channel control bus is created, and assigned to the pre-declared variable b.
  • For synth creation, x is assigned a control-rate synth, while y and z are assigned audio-rate synths. Each synth is given the variable b, which refers to our control-rate bus. z is also given an argument for \freqOffset, which makes its frequency 200 Hz higher than the synth assigned to y.
  • Don't worry about the after message for now. It's explained in Section 11.3.12.1, “Ordering”.
11.3.11.4.1. Why Use Global Variables
Since this is just an example, and not an actual program, the program uses four automatically-declared global variables: b, x, y, and z. Because these variables are shared with everything, it's especially important to set them to nil when you're done. If this were going to be written into a real program, it would be a good idea to change the variables to something which can't be accessed by other programs.