 (ns overtone.examples.busses.getonthebus
   (:use overtone.live))
 
-;; Here's some code to help get you going with busses.
-;; (Audio busses to be precise, but I'm fuzzy enough on the
-;; difference between audio and control busses that I'm not
-;; going to attempt to explain it here).
-;;
 ;; Busses are like wires or pipes that you can use to connect the output
-;; of one synth to the inputs of one or more other synths.  (I haven't
-;; tried connecting the outputs of more than one synth to the same
-;; bus so I'm not sure how well that would work).
+;; of one synth to the inputs of one or more other synths.
+;; There are two types of busses - control busses and audio busses.
 
-;; First here are some busses to carry some signals
-(def tri-bus (audio-bus))
-(def sin-bus (audio-bus))
+;; Control busses are designed to carry control signals - values changing
+;; at a human rate (i.e. the speed you may turn a dial or slide a slider).
+
+;; Audio busses are designed to carry audio signals - values changing at
+;; a rate that makes them audible.
+
+;; Audio busses can carry both audio and control rate signals. However,
+;; they will use more computational resources. Therefore, consider using
+;; a control bus if you're signal doesn't need to change more than, say,
+;; 60 times a second.
+
+;; You can create many new control and audio busses. However, your system
+;; will start with one audio bus per audio input and one audio bus per audio
+;; output. For example, your left speaker is represented by audio bus 0
+;; and your right speaker is represented by audio bus 1
+
+;; Let's create some busses to carry some control rate signals
+
+;; We use the defonce construct to avoid new busses being created and
+;; assigned accidentally, if the forms get re-evaluated.
+(defonce tri-bus (audio-bus))
+(defonce sin-bus (audio-bus))
 
 ;; These are synths created to send data down the busses.
-;; They are set up so that you can use the ctl function after
-;; they're triggered to change the bus that they output on
-;; or the frequency at which their ugen is operating.
+;; They are set up so that you can modify both the bus they output on and
+;; their frequency whilst they're running via standard ctl messages.
+;;
+;; Note that we use the :kr variant of the out ugen. This tells the synth
+;; to output to a control bus rather than an audio bus which is the default.
 (defsynth tri-synth [out-bus 0 freq 5]
-  (out out-bus (lf-tri:ar freq)))
+  (out:kr out-bus (lf-tri:kr freq)))
 
 (defsynth sin-synth [out-bus 0 freq 5]
-  (out out-bus (sin-osc:ar freq)))
+  (out:kr out-bus (sin-osc:kr freq)))
 
-;; Evaluate these to start sending signals to the busses
-;; Note that if any of the subsequent instantiations of synths end up with
-;; synths that are not being modulated (i.e. that are just outputting a
-;; single frequency at an unchanging volume, or that sound like they
-;; aren't outputting anything at all) you probably need to re-evaluate
-;; one or both of these, and then possibly you'll need to kill and
-;; re-create the synths (I'm not sure why; seems like that shouldn't
-;; be necessary but that's how it goes).
+;; Probably the most important lesson about using busses is to understand that
+;; the execution of the synthesis on the server is strictly ordered. Running
+;; synths are placed in a node tree which is evaluated in a depth-first order.
+;; This is important to know because if you want synth instance A to be able to
+;; communicate with synth instance B via a bus, A needs to be *before* B in the
+;; synthesis node tree.
+
+;; The way to gain control over the order of execution within the synthesis tree
+;; is to use groups. Let's create some now:
+
+(defonce main-g (group "get-on-the-bus main"))
+(defonce early-g (group "early birds" :head main-g))
+(defonce later-g (group "latecomers" :after early-g))
+
+;; Let's create some source synths that will send signals on our busses. Let's
+;; also put them in the early group to ensure that their signals get sent first.
+
 (comment
-  (def tri-synth-inst (tri-synth tri-bus))
-  (def sin-synth-inst (sin-synth sin-bus))
+  (def tri-synth-inst (tri-synth :tgt early-g tri-bus))
+  (def sin-synth-inst (sin-synth :tgt early-g sin-bus))
   )
 
-;; These synths are what actually make sound (because their outputs
-;; are going to the 0 and 1 busses, a.k.a. the left and right channels
-;; of the audio output).
+;; Notice how these synths aren't making or controlling any sound. This is because
+;; they're control rate synths and also because their output is going to the busses
+;; we created which aren't connected to anything. The signals are therefore ignored.
 
-;; For each sample, this one reads the value off the bus (at audio rate)
+;; We can verify that they're running by viewing the node tree. We can do this
+;; easily with the following fn:
+(pp-node-tree)
+
+;; This will print the current synthesis node-tree to the REPL. This can get pretty
+;; hairy and large, but if you've only evaluated this tutorial since you started
+;; Overtone, it should be pretty manageable. You should be able to see the tri-synth
+;; and sin-synth within the early birds group, which itself is within the
+;; get-on-the-bus main group which itself is within the Overtone Default group.
+
+;; Now, let's use these signals to make actual noise!
+
+;; First, let's define a synth that we'll use to receive the signal from the bus to
+;; make some sound:
+
+(defsynth modulated-vol-tri [vol-bus 0 freq 220]
+  (out 0 (pan2 (* (in:kr vol-bus) (lf-tri freq)))))
+
+;; Notice how this synth is using the default audio rate version of the out
+;; ugen to output a signal to the left speaker of your computer. It is also
+;; possible to use out:ar to achieve the same result.
+
+;; This synth reads the value off the bus (at control rate)
 ;; and multiplies it with the lf-tri ugen's sample value.  The overall
-;; result is then sent to two busses: 0 and the one above it. (pan2 duplicates
+;; result is then sent to two consecutive busses: 0 and 1. (pan2 duplicates
 ;; a single channel signal to two channels; this is documented in more detail
 ;; in some of the getting-started examples).
-(defsynth modulated-vol-tri [vol-bus 0 freq 220]
-  (out 0 (pan2 (* (in:ar vol-bus) (lf-tri freq)))))
 
-;; This one is a little trickier.  It calculates the frequency
+
+;; This synth is a little trickier.  It calculates the frequency
 ;; by taking the sample value from the bus, multipling it by
 ;; the frequency amplitude, and then adding the result to the midpoint
 ;; or median frequency.  Therefore, if you hook it up to a bus carrying

;; you'll get an lf-tri ugen that oscillates between 165 and 275 Hz
;; (165 is 55 below 220, and 275 is 55 above 220)
(defsynth modulated-freq-tri [freq-bus 0 mid-freq 220 freq-amp 55]
  (let [freq (+ mid-freq (* (in:ar freq-bus) freq-amp))]
    (out 0 (pan2 (lf-tri freq)))))




;; Or can re-use them!
(comment
  (def mvt-2 (modulated-vol-tri :tgt later-g sin-bus 110))
  (kill mvt-2)
  )

