GUI and OSC

Assign: Thursday, November 18

Due: Thursday, December 2

Assignment Policies

All assignments are partner assignments. Please make sure to review the policies and guidelines about discussing assignments with those other than your partner. Assignments are usually, but not always, a combination of paper and coded exercises. Please make two submissions (one for paper exercises and one for coded exercises) to Gradescope. Paper exercises are marked with HW to indicate a handwritten question and C to indicate a coded question. Paper submissions can receive an extra 2% bonus if they are typed. Please visit the tools section of the website for more information.

Part 1: Pulse Dream

To get started, download the starter code.

In this part, you will write a GUI interface to control a pattern in real time. The pattern and its SynthDef are given to you already. The interface should look similar to the one pictured below:

The interface was created with the following specifications:

Understanding the Starter Code

The SynthDef used in the pattern plays back pulse waves in octaves that run through a resonant lowpass filter. The second half of the starter code has a pattern wrapped in a function. If you execute the block, you will not hear anything. To hear how the pattern sounds, run the following:

(
~pat.value;
~evp.play;
)

Take a careful look at the ~pat function that is used to play the pattern. All of the features that we want to change with the GUI are given as environment variables with default values. Inside the Pbind, we use the pattern Pfunc to yield the value of the environment variable. This allows us to change the environment variable’s value and have it update the pattern in real time. For example, start the pattern and run ~amp = 0.4. The pattern should now sound twice as loud.

Details about the Knobs and Buttons

You should implement your GUI at the bottom of the starter code as a single code block. The very first line should be to run the pattern function. This has been given to you:

(
~pat.value
// Your code here

)

Note that if you want to declared any local variables for the code block (which you should) that those should be placed above the line ~pat.value. Below are the specific details for each button and knob.

Play and Stop Button

When the GUI starts up, the pattern should initially be silent. When the user clicks on the “Play” button, the pattern should start playing by running the code ~evp.play. When the user clicks on the “Stop” button, the pattern should stop playing by running the code ~evp.stop.

You are welcome to choose any color, text formatting (note that you must use the words “Play” and “Stop”), margins, or other styling. In my implementation, I made the buttons 180x180 with 10 unit margins but feel free to choose something different. Note that you must implement the functionality stated above.

The Knobs

Each knob is required to control their respective parameter of the GUI. Remember to use the method .linlin to map the range of the knob’s values to something other than 0 to 1.

Amplitude Knob:

Duration Knob:

Pulse Width Knob:

Cutoff Frequency Knob:

Pan Knob:

Attack Time Knob:

IMPORTANT: The image above shows the GUI when it is first launched. Notice how the knobs are set to the initial default values provided by the environment variables set in ~pat. Your GUI should start with those initial settings on the knobs. The easiest way to do that is to set the value of each knob. For example, if I have a knob stored in the variable ~k and want to set it to the value of 0.2, I can simply write ~k.value = 0.2. Be careful! The knob for the cutoff frequency, for example, should initially be set to a frequency of 1000Hz. That will need to be mapped to the range of 0 to 1.0 first and then set.

Grading

You will be graded on the following criteria:

Part 2: PyCollider

To get started, download the starter code.

SuperCollider was designed to integrate with other audio software and programming languages via OSC. In fact, many programmers have used SuperCollider as the backend audio engine for a variety of different interesting projects. Many of them are listed on SuperCollider’s main webpage. One very cool project is FoxDot which uses Python as the user language to produce audio with SuperCollider. How does that work? Both SuperCollider’s language sclang and server scsynth can listen for incoming messages across a network and respond to those messages to produce sound.

In this part, we will build a SuperCollider program to respond to OSC messages from a python client contained in the module client.py that accompanies your starter code. The client sends messages to play one of three types of waves: a sine wave, a triangle wave, and a square wave. In SuperCollider, three OSCDefs respond to their respective waveform messages from the client and create synths to play those sounds. Your task will be to write the SuperCollider backend. The client has been written for you.

Overview of SuperCollider Backend

On the backend SuperCollider should produce synths for a sine wave, triangle wave, and square wave. The backend should have three OSCDefs listening for incoming OSC messages and produce the requested synth on the audio server. The requirements for each OSCDef is as follows:

Python client:

>>> from client import *
>>> connect()
>>> sine(300, 0.1)
>>> square(600, 0.1)
>>> tri(400, 0.2)

SuperCollider Post Window:

Sine Wave from a NetAddr(127.0.0.1, 61685):
- Freq: 300 | Amp: 0.10000000149012
Square Wave from a NetAddr(127.0.0.1, 61685):
- Freq: 600 | Amp: 0.10000000149012
Triangle Wave from a NetAddr(127.0.0.1, 61685):
- Freq: 400 | Amp: 0.20000000298023

And of course, we should hear a sine wave, followed by a square wave, followed by a triangle wave.

Overview of the Client: client.py

If you have taken CS111, you should already have python installed on your machine through Anaconda and Thonny. You can also use Canopy as well if you took an older version of CS111. Depending on your comfortability/preference you can either run the client from the Command Line or in Thonny.

Option 1: Command Line

If you want to use the Command Line you will have to install a package for Python called python-osc. Run the following:

pip install python-osc

Then you can simply run python.

Option 2: Thonny

If you want to use Thonny (which I recommend if you are unsure about how to use the command line), then execute the following instructions:

  1. Go to Tools, then Manage Packages…, search for python-osc, and then hit install.
  2. Open client.py and then run the file using the Green arrow button.

In the python shell (either through the command line or through Thonny), you can run the functions provided for you by client.py. The details of the functions are below:

To get started sending messages to SuperCollider, always run these two lines first:

>>> from client import *
>>> connect()

Note that you must run Python from the folder that contains client.py.

Grading

You will be graded on the following critera:

You can of course expand the relationship between both client.py and the SC backend to implement any of the functionality of SuperCollider in Python. Extra credit will be given if you make significant additions to the functionality and document them in your submission.

Submission

Feedback

When you are finished with the problem set, please fill out the form linked here to provide feedback on how long the problem set took you and how difficult you found it. Note that you must fill out this form to receive credit for the problem set.

Submission Guidelines

All assignments in this course are submitted through Gradescope. There are two kinds of assignments in this course: paper assignments and code assignments. Both are submitted to Gradescope. Most assignments are a mix of code and paper assignments. Each question or question part will be marked either “code” or “paper” to indicate which kind of question it is. For paper assignments, note that typed answers will receive a small additional bonus of 2%.