* Haskell SuperCollider, a Tutorial. * Prerequisites Haskell SuperCollider requires that SuperCollider [1], GHC [2], the GHC binary package[3], Emacs [4] and the standard Haskell Emacs mode [5] are all installed and working properly. * Setting up Haskell SuperCollider Haskell SuperCollider is currently only available as a set of darcs repositories, the first implementing the Sound.OpenSoundControl module, the second the Sound.SC3 module. $ darcs get http://slavepianos.org/rd/sw/hosc $ darcs get http://slavepianos.org/rd/sw/hsc3 To build use the standard Cabal process in each repository in sequence. $ runhaskell Setup.lhs configure --prefix ~ $ runhaskell Setup.lhs build $ runhaskell Setup.lhs install --user * Setting up the Haskell SuperCollider Emacs mode Add an appropriately modified variant of the following to ~/.emacs (push "~/sw/hsc3/emacs" load-path) (setq hsc3-interpreter "ghci") (setq hsc3-help-directory "~/sw/hsc3/Help/") (require 'hsc3) The hsc3 emacs mode associates itself with files having the extension '.lhs'. When the hsc3 emacs mode is active there is a 'Haskell SuperCollider' menu available. * Literate Haskell The documentation for Haskell SuperCollider, including this tutorial, is written in 'Bird' notation, a form of 'literate Haskell' where lines starting with '>' are Haskell code and everything else is commentary. Unlike ordinary literate programs the Haskell SuperCollider help files cannot be compiled to executables. Each help file contains multiple independant examples that can be evaluated using editor commands, either by selecting from the 'Haskell SuperCollider' menu or using the associated keybinding. * Interpreter Interaction To start ghci and load the list of modules at the emacs variables 'hsc3-main-modules' and 'hsc3-modules' use C-cC-s (Haskell SuperCollider -> Haskell -> Start haskell). By default 'hsc3-main-modules' is empty and 'hsc3-modules' contains Sound.OpenSoundControl, Sound.SC3, Data.List, Control.Monad, Control.Concurrent, System.Directory and System.Random. Starting the interpreter splits the current window into two windows. If the ghci output window becomes obscured during a session you can see it again by typing C-cC-g (Haskell SuperCollider -> Haskell -> See output). To stop ghci type C-cC-x (Haskell SuperCollider -> Haskell -> Quit haskell). * Starting the SuperCollider server The SuperCollider server can be started from the command line. The help files assume that scsynth is listening for UDP connections at the standard port on the local machine. $ scsynth -u 57110 * Basic SuperCollider Interaction The SuperCollider server manages a graph of nodes with integer identifiers. The root node has ID zero. By convention ordinary graph nodes are placed in a group with identifier 1, however this node is not created when scsynth starts. To create this node we need to send an OSC message to the server, the expression to do this is written below. To run single line expressions move the cursor to the line and type C-cC-c (Haskell SuperCollider -> Expression -> Run line). > withSC3 (\fd -> send fd (g_new [(1, AddToTail, 0)])) We can then audition a quiet sine oscillator at A440. > audition (out 0 (sinOsc AR 440 0 * 0.1)) To stop the sound we can delete the group it is a part of, the audition function places the synthesis node into the group node with ID 1, the expression below deletes that group. > withSC3 ((flip send) (n_free [1])) In order to audition another graph we need to re-create a group with ID 1. Sound.SC3 includes a function 'reset' that sequences these two actions, first deleting the group node, then re-creating a new empty group. > withSC3 reset Using this command is so common there is a keybinding for it, C-cC-k (Haskell SuperCollider -> SCSynth -> Reset scsynth). After a reset we can audition a new graph. > audition (out 0 (sinOsc AR 220 0 * 0.1)) To see the server status type C-cC-w (Haskell SuperCollider -> SCSynth -> Display status). This prints a table indicating server activity to the ghci output window. ***** SuperCollider Server Status ***** # UGens Int 3 # Synths Int 1 # Groups Int 2 # Instruments Int 1 % CPU (Average) Float 2.6957032680511475 % CPU (Peak) Float 2.7786526679992676 Sample Rate (Nominal) Double 44100.0 Sample Rate (Actual) Double 44099.958404246536 * Multiple line expressions To evaluate expressions that don't fit on one line select the region and type C-cC-e (Haskell SuperCollider -> Expression -> Run region). To select a region use the mouse or place the cursor at one end, type C-[Space] then move the cursor to the other end. > let f = sinOsc AR (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800 > audition (out 0 (sinOsc AR f 0 * 0.1)) This writes the region in a do block in a procedure to a temporary file, /tmp/hsc3.lhs, loads the file and then runs the procedure. The preamble imports the modules listed at the emacs variable hsc3-modules. * Help Files To find help on a UGen or on a SuperCollider server command place the cursor over the identifier and type C-cC-h (Haskell SuperCollider -> Help -> Haskell SuperCollider help). This opens the help file, which ought to have working examples in it, the above graph is in the sinOsc help file, the s_new help file explains what arguments are required and what they mean. The Haskell SuperCollider help files are derived from the help files distributed with SuperCollider, the text is re-formatted to read well as plain text and examples are translated into Haskell. There is also partial haddock documentation for the Sound.SC3 and Sound.OpenSoundControl modules, to build type: $ runhaskell Setup.lhs haddock * User configuration files It is straightforward to add configuration modules to the context in which the hsc3 emacs mode evaluates expressions using the 'hsc3-main-modules' variable. The search path for these modules can be set using 'hsc3-interpreter-arguments'. (setq hsc3-interpreter-arguments (list "-i/home/rohan/.hsc3")) (setq hsc3-main-modules (list "Config")) * Monitoring incoming server messages To monitor what OSC messages scsynth is receiving use the 'dumpOSC' server command to request that scsynth print text traces of incoming messages to its standard output. > withSC3 ((flip send) (dumpOSC TextPrinter)) To end printing send: > withSC3 ((flip send) (dumpOSC NoPrinter)) * References [1] http://www.audiosynth.com/ [2] http://www.haskell.org/ghc/ [3] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary-0.3 [4] http://www.gnu.org/software/emacs/ [5] http://www.haskell.org/haskell-mode/