Music 147 assignment for Tuesday June 3, 2014

The topic in class will be inter-application communication—be it within one computer, via network, or wirelessly. You should inform yourself about the principles involved and some of the methods that have been established for accomplishing such communication, and be prepare to explain and discuss those topics in class.

Learn about ReWire by reading its general description and some technical details.

Learn about Jack and the Jack API.

Learn about JackTrip, by reading about how it works and what the JackTrip library contains.

Learn about the Open Sound Control (OSC) protocol, and the TouchOSC application for wireless handheld devices.

 

Music 147 assignment for Thursday May 29, 2014

Read the first part of the chapter on “Filters” in Miller Puckette’s The Theory and Technique of Electronic Music, at least through the section called “Taxonomy of Filters”.

If you haven’t yet done so, study the MSP Tutorial chapters from the previous assignment:

MSP Tutorials 27-31.
27. Delay Lines
28. Delay Lines with Feedback
29. Flanging
30. Chorus
31. Comb Filter

 

Ocarina iPhone app article in CMJ

The Summer 2014 issue of the Computer Music Journal (which you can read for free by accessing it from the UCI LAN or via VPN tunnel to UCI) has several articles of relevance to this course, including “Ocarina: Designing the iPhone’s Magic Flute” written by Ge Wang, author of Ocarina, the most popular music app for iOS to date and one of the top 20 downloaded apps of all time.

Wang, Ge. “Ocarina: Designing the iPhone’s Magic Flute”. Computer Music Journal, Volume 38, Number 2, Summer 2014, pp. 8-21 (Article). Cambridge, MA: The MIT Press, 2014.

iOS Oscillator app

I have posted an Xcode project for a bare-bones iOS app called Oscillator. It plays a sine tone and allows the user to adjust the amplitude and the frequency (exponentially from -40 dB to 0 dB and from A-110 Hz to A-1760 Hz). It’s not very sophisticated conceptually, technically, or aesthetically, but it does demonstrate the basics of a) mapping user interface objects to methods, b) writing an audio callback function, and c) implementing wavetable synthesis. There’s a fair bit of commentary in the .h and .m files.

Music 147 assignment for Tuesday May 27, 2014

Come to class prepared to do a very brief demonstration of your programming project in progress. It should be a demonstration of what you’ve accomplished so far, the decisions you’ve made, the problems you’ve solved, and the problems that you have not yet solved (to solicit ideas from your classmates).


In preparation for the upcoming discussion of delay-based effects, read the Wikipedia article about the “Circular buffer“. Many interesting audio effects are achieved by combining a sound with a delayed (and possibly altered) version of itself. To delay a sound, one needs to store it for a certain amount of time till (a delayed copy of) it is needed. That storage has to be constantly ongoing when we’re dealing with realtime audio processing, yet we usually also want to dispose of the delayed audio data once it’s no longer needed. Realtime delay of audio is therefore most often achieved by storing the sound in what’s commonly called a ring buffer or a circular buffer.

Study MSP Tutorials 27-31.
27. Delay Lines
28. Delay Lines with Feedback
29. Flanging
30. Chorus
31. Comb Filter

 

Probability distribution vector

A computer can make a choice between different alternatives based on assigned statistical “likelihoods”—relative probabilities assigned to each possible alternative. This is accomplished most easily by storing all of the probabilities in a single vector (array), calculating the sum of all those probabilities, dividing the range (0 to the sum) into “quantiles” (subranges) proportional to the different probabilities, choosing a random number within that range, and determining which quantile the random number falls into.

The article “Probability distribution” describes this process and shows how to accomplish it, both conceptually (in a prose description that could be implemented as a program) and with an example written in Max using the table object. That article also discusses the implications and limitations of making decisions in this way.

What follows is an example of how to implement a probabilistic decision making program in JavaScript, and a simple Max patch for testing it. I chose to write the example in JavaScript for two reasons. One reason is that JavaScript is an easy-to-understand language, comprehensible to people who already know Java or C; the other reason is just to demonstrate how easy it is to write and use JavaScript code inside Max.

First, let’s recap the process we’ll follow, as stated in that article.
1. Construct a probability vector.
2. Calculate the sum of all probabilities.
3. Choose a random (nonnegative) number less than the sum.
4. Begin cumulatively adding individual probability values, checking after each addition to see if it has resulted in a value greater than the randomly chosen number.
5. When the randomly chosen value has been exceeded, choose the event that corresponds to the most recently added probability.

To see an implementation of this in JavaScript for use in the Max js object, download the file “probabilisticchoice.js” and save it with that name somewhere in the Max file search path. The comments in that file explain what’s being done. In this implementation, though, we use a reverse procedure from the one described in step 4 above. We start by subtracting the value of the last probability in the array from the total sum, and checking to see if that value is less than the random number we chose. If not, we proceed to the next-to-last probability, subtract that, and see if it’s less than the random number, and so on. The principle is the same, we’re just checking downward from the maximum rather than upward from the minimum.

You can try out the program using the example Max patch shown below.


probabilitiestester.maxpat

The JavaScript program accommodates the six input messages shown in the patch. To set the array of probabilities, one can use the setprobabilities message or simply a list. One can query the contents of the variables probabilities, choices, and sum variables, which are sent out the right outlet. The message bang makes a probabilistic choice based on the specified probabilities, and sends the choice (some number from 0 to choices-1) out the left outlet. Note that this is nearly identical to the probabilistic choice capabilities of the table object. It’s shown here as a JavaScript to demonstrate the calculation explicitly.

Music 147 assignment for Thursday May 22, 2014

In preparation for the discussion of score following and interactive computer-mediated performance, read the CD liner notes for, and listen to the composition There’s Just One Thing You Need to Know for Disklavier piano, synthesizer, and interactive computer system.

In preparation for the discussion of computer cognition of gesture, read “A Method for Computer Characterization of ‘Gesture’ in Musical Improvisation“. If you would like to see and hear the described computer algorithm in action, watch a video of an in-studio improvisation and a video of a live concert improvisation. (If you have not already done so, you should also do the portion of the previous assignment that relates to gesture recognition, reading and watching the “Gesture Follower” presentation made by the research team on Realtime Musical Interactions at IRCAM.)

Tap to set tempo

Instead of the user entering a tempo value by hand, it’s possible to have the computer measure the tempo at which the user is tapping the beat. Do do that, you simply need to measure the time difference between two events (taps).


taptempo-simple.maxpat

In this example, I use the ‘t’ key of the computer keyboard (t for tempo, or for tap) to set the tempo attribute of the transport. The timer object measures the time between a bang in its left inlet and a bang in its right inlet. Note that, because of the right-to-eft message-order rules of Max, a bang to both inlets of timer coming from the same outlet of another object will first go to timer‘s right inlet, sending out the time since the previous bang in the left inlet, and only then will it go to timer‘s left inlet to serve as the starting event for the next interval to be timed. Thus each bang message triggered by the ‘t’ key will serve as both the ending event for one time interval measurement and the starting event for the next time interval measurement.

I use a split object to pay attention only to time intervals that would yield a reasonable tempo. I determined that metronomic tempos between 30 and 300 provides an ample range of possibilities. A tempo of 300 bpm implies a beat interval of 200 ms, and a tempo of 30 bpm implies a beat interval of 2000 ms. This also serves the crucial function of filtering out (ignoring) extremely short values that might result from the user inadvertently double-tapping the ‘t’ key, and it filters out the extremely long time intervals that would be measured when the user first taps after not having tapped for a long time. The millisecond time interval between taps is then divided into 60,000 (the number of milliseconds in a minute) to calculate the tempo in terms of beats per minute. (The object !/ means “divide into”, as opposed to / which means “divide by”.) That bpm value is then used as the argument in a tempo message to transport to set the tempo of the global transport in Max. (You can probably imagine how this tap-tempo functionality could be used in conjunction with the metronome demonstrated in the previous example.)

This tap tempo patch allows the user to set the tempo as quickly as possible, with just two taps. There are a couple potential downsides of this quickness, however. One is that the tempo leaps immediately to a new rate with each tap, which could possibly result in some jarring changes. The other is that the user must tap at precisely the right tempo on the first try, or else must keep re-tapping till the right tempo is achieved. A possible method of addressing those potential problems might be to take the average of a few successive taps, thus leading to a slightly more gradual (but still pretty efficient) change to a new tempo. That approach is demonstrated in a tap tempo example from a previous class.