2020-2021 Class


For the first online edition of the SPRAWL class, all students were equipped with the original Access Points, used for the original approach. The concept relied on irregular weekend sessions with additional meetings during the week.

In each session, the SPRAWL System was used for audio connections. Video and additional talkback for trouble shooting was realized with a parallel Zoom session, as shown in the figure below. For leave streams, as in the closing concert, the audio from the Jacktrip connections is merged with the video from the Zoom meeting, by means of OBS on an additional Acess Point dedicated to straming.


Video stream during the closing concert.

Scores and Compositions

Several conepts were explored during the semester, including graphic scores, text-based compositions and configuration-based improvisations.

Graphic Scores

Graphic scores are a simple but effective means for guiding improvisations in network performances. They can be distributed to all participants via screen sharing to ensure a decent synchronization.


Blodgett is a text-based score by Robert Stokowy, comissioned by the EOC in 2019:


The score gives precise instructions on the spatial behavior of the sound sources. In the SPRAWL System, each participant takes control of his/her own source position, thus sharing the task of spatialization. Focusing on simple properties like proximity/distance and movement/stillness, each student programmed a Pure Data patch, allowing a GUI-based control on the default Access Points' touch screen.

Granular Confusion

Granular Confusion is a concept by Mario Hillenbrand, developed for the SPRAWL System. The Access Points are devided into sound generators and processors:

  • Generators can use any means for sound generation.
  • Processors are all running the same granular patch.

The Access Points are statically connected, as shown in the figure below. An additional sound director takes care of spatialization and manages the start/stop procedure of the configuration. A minimal timeline is used to guide the iprovisation, telling the generators when to be active.


Signal routing for Granular Confusion.

Back to NSMI Contents

Compiling JackTrip

The SPRAWL System needs some additional features that are missing from the main branch of Jacktrip. To build the correct JackTrip version, the Jacktrip git repository must be cloned and checked out to the correct branch.

Therefor git must be installed. On MacOS git is often already installed. Linux users should install git through their package manager. Windows users download the installer from git-scm.

Getting the JackTrip Source Code

Now the JackTrip source code can be downloaded from the official JackTrip repository.

git clone https://github.com/jacktrip/jacktrip.git
git checkout nils

Changes in the remote repository have to get pulled.

git pull

Afterwards you can follow the official build instructions.

Moving Files with SCP

SCP (Secure copy protocol) is an SSH-based tool for transferring files between machines in local and wide area networks. It is a safe and quick way to exchange data.

Copying to a Remote Machine

The following command copies the file testfile.html from the local machine to the home directory of the user student on the server with the address specified address 11.22.33. Instead of the home directory (~/), any other target can be specified:

$ scp testfile.html student@11.22.33:~/

Add the -r flag to copy a directory recursively:

$ scp -r /foo/bar student@11.22.33:~/

.. admonition:: Exercise

  Select or create a short WAV file on your local machine and copy it to your personal directory on the server using SCP.

Copying From a Remote Machine

To copy a file from a remote server, the arguments' order needs to be swapped. The dot (.) copies the data to the recent directory. Any other path can be used as target.

$ scp student@ .


Create a text file in your personal directory on the server. Copy it to your local machine using the SCP command from your local machine.

Using Python for Control

Python offers many useful tools for preparing data and controlling synthesis processes. Although it can also be used for actual digital signal processing, its versatility makes it a great tool for auxuliary tasks. Most notably, it can be used for flexible processing and routing of OSC messages, especially in the field of data sonification.

Python & OSC

A large variety of Python packages offers the possibility of using OSC. They can be installed using pip:

$ pip install python-osc
$ pip install pythonosc

An example project for controlling a Faust-built synthesizer with Python is featured in this software repository: https://github.com/anwaldt/py2faust_synth

Python & JACK

The JACK Audio Connection Kit Client for Python by Matthias Geier connects Python processes to the JACK server. This integration of Python in a JACK ecosystem can be helpful not only for audio processing, but also for synchronization of processes. Since the Python package also implements the JACK transport functions, it can be used to couple Python threads to the timeline of audio projects.

Using Buses in SuperCollider

Control Rate vs Audio Rate

SC works with two internal signal types or rates. When something is used with the extension .ar, this refers to audio signals (audio rate), whereas .kr uses the control rate. For both rates, buses can be created.

Creating Buses

An audio bus with a single channel is created on the default server s with the following command:

~aBus = Bus.audio(s,1);

A control bus with a single channel is created on the default server s with the following command:

~cBus = Bus.control(s,1);

Bus Indices

The variable ~aBus is the client-side representation of the Bus. The server only knows it by its bus index. Bus indices are counted upwards and can be queried with the following command:


Monitoring Buses

Any bus can be monitored with the builtin scope with the following command. The first argument defines the number of buses to be shown, the second the index of the first buses:


There is a short version, which has limitations and does not specify the bus type:


Control Buses

This simple sawtooth node will be used for showing how to use control buses. It has one argument freq, which affects the fundamental frequency and uses the first hardware output:

~osc  = {arg freq=100; Out.ar(0,Saw.ar(freq))}.play;

Mapping a Control Bus

The map() function of a node can connect a control bus, identified by its index, with a node parameter:


Setting a Control Bus

After mapping the bus, the synth stops its sound., since the control bus is still set to the default value 0. This can be visualized with the scope command. A simple and quick way for changing the control bus to a different value is the set() function of a node. It can be used for all arguments of the node which are internally used for control rates:


Multichannel Buses

Both control and audio rate buses can be created as multi channel buses. A scope will automatically show all channels. Individual channels can be mapped with an offset in relation to the index of the first channel. The setAt() function can be used for changing individual channel values:

~mBus = Bus.control(s,8);




Patches and Subpatches in Pure Data


The following examples are based on patches and additional files, called abstractions. To make them work, all involved patches need to be located in the same direction (by cloning the complete repository). Arguments are passed to objects after the name, separated by a white space. The patch arguments-help.pd shows this by creating an arguments object:


Inside an abstraction, individual arguments can be accessed with the $ operator and their index. The loadbang is executed on the object's creation, thus printing both arguments on start. This is helpful for setting initial values in patches, as shown in arguments-help. Once created, it will print the arguments to the main Pd window:



Subpatches can be very helpful for creating cleaner patches without addtional abstractions and files. To create a subpatch, use the object pd with an optional string argument for naming the subpatch. They can be used like abstractions but do not require an additional file.


When toggling Graph-on-Parent in an object's properties, it can expose GUI elements to its parent patch. This is a good way of cleaning your patch and showing only what is needed in a performance situation. It works for both abstractions and subpatches. The example patches.pd makes use of this to create a filter subpatch with controls. The left hand audio input of the suppatch is a fixed frequency sawtooth. The right hand control input sets the Q of the filter.


On the inside, the moog~ object is used. It is not part of PD vanilla and can be installed with the flatspace ggee extensions from Deken. The red rectangle marks the area visual in the parent patch. All GUI components inside this area will be visible:


Inlets and Outlets

The patch has two inlets - one in audio rate (inlet~) and one in control rate - and two outlets, also with audio rate (outlet~) and control rate. For inlets and outlets, their horizontal order determines their order in the object when patched from the parent. Changing them can mess up the complete patching.

Using OSC in Pure Data

Vanilla Only

Sending OSC

The default version of PD is referred to as Vanilla. OSC can be used in Puredata without further packages, by means of the ojects netsend, oscformat and oscparse. The patch osc-send-vailla.pd sends a message to port 6666 on the localhost ( The message has the following structure and contains one float argument:

/oscillator/frequency/ [float]


Receiving OSC

The corresponding receiver patch osc-receive-vanilla.pd listens on port 6666. Using the route object, the message is unwrapped until the single float argument can be processed by the number box:



Send messages between the patches. If possible, use two computers and change the address in the send patch.

Using Externals


Sending OSC

The following example is based on additional externals. For using them, install the external mrpeach with the Deken tool inside Puredata: https://puredata.info/docs/Deken The send patch uses the hostname localhost instead of an IP address. The path /oscillator/frequency of the OSC message has been defined arbitrarily - it has to match between client and receiver. Before sending OSC messages, the connect message needs to be clicked.


Receiving OSC

Before receiving OSC messages, the udpreceive object needs to know which port to listen on. Messages are then unpacked and routed according to their path, using the routeOSC object.



Use both patches for a remote controlled oscillator. If possible, use two computers and change the address in the send patch.


  • Miller S. Puckette. Pure Data. In Proceedings of the International Computer Music Conference (ICMC). Thessaloniki, \\ Greece, 1997.
  • Miller S. Puckette. The patcher. In Proceedings of the International Computer Music Conference (ICMC). Computer Music Association, 1988.
  • More APIs

    There are many more APIs which can be used for real time or off line sonification. Several projects and meta sites list examples by category:


    NASA offers a great variety of open APIs with data from astronomy: https://api.nasa.gov/

    AM & Ringmodulation: Example

    The following example shows both AM and ring modulation:

    Carrier Frequency

    Modulator Frequeny

    Modulator Offset

    Output Gain:

    Time Domain:

    Frequency Domain:

    Sampling & Aliasing: Sine Example

    In the following example, a sine wave's frequency can be changed with an upper limit of $10\ \mathrm{kHz}$. Depending on the sample frequency of the system running the browser, this will lead to aliasing, once the frequency passes the Nyquist frequency:

    Pitch (Hz):

    Output Gain:

    Time Domain:

    Frequency Domain:

    Contents © Henrik von Coler 2021 - Contact