Week 4, Improvising with Algorithms

Class Summary

This week, we started by watching a track from my album Natural Machines that uses one of the simplest algorithms there is, a canon at the octave:
https://www.youtube.com/watch?v=OAu2MWzTq3M

We followed that with an introduction to the SuperCollider programming environment. Eventually, we built up the following block of code, a basic version of the algorithm I use in the track:

(

MIDIClient.init;
MIDIIn.connectAll;

~midiOut = MIDIOut.newByName("IAC Driver", "Bus 1");
~midiIn = MIDIIn.findPort("DKV-M4", "Port1");

~interval = 12;
~delay = 0.3;

MIDIFunc.noteOn({
arg onVeloc, onNum;
var transformedNum = onNum + ~interval;

"midi received ".post; onNum.postln;

SystemClock.sched(~delay,{
~midiOut.noteOn(0, transformedNum, onVeloc);
});

MIDIFunc.noteOff({
arg offVeloc, offNum;
SystemClock.sched(~delay,{
~midiOut.noteOff(0, transformedNum, offVeloc);
});
}, srcID: ~midiIn.uid, noteNum: onNum).oneShot;


}, srcID: ~midiIn.uid);


)

Before you run this code block,  position your cursor over this line:

MIDIClient.init;

and type shift-return (or shift-enter on PC). This will execute that line only. In the post window (bottom right of your SC screen), SC will list the MIDI devices that are currently connected.

Then, in the following two lines,

~midiOut = MIDIOut.newByName("IAC Driver", "Bus 1");
~midiIn = MIDIIn.findPort("DKV-M4", "Port1");

Replace the names in quotes with the names of the input and output MIDI devices you are using. On Mac, the first one will stay the same as I have it here. 

Then, position your cursor anywhere in the code block and type command-return (or control-enter on PC) to execute the entire code block. Now, when you play on your MIDI device, you should see the MIDI number of the note you just played appear in the post window, and you should hear, about 0.3 seconds later, the same note an octave up in your output MIDI device (Logic, GarageBand, Reaper, etc — whatever is producing your sounds). 

Important: to stop the program from executing, type command-period, or control-period on PC.

Note that these variables: 

~interval = 12;
~delay = 0.3;

are global variables, because they’re preceded by the ~ sign. This, among other things, means we can change their value on the fly. So, while the program is still running, you can change the values of these parameters by just editing the text, then position your cursor over the line and hit shift-return to run that line. That will immediately change the value used by the algorithm. 

So, in your improvisation, you could start with a 0.3 sec delay and change it to 0.6, for example, or you could do your improvisation with gradually shrinking intervals. The beauty of programming is that anything is possible. 

Please submit an improvisation this week that uses this program. Please keep it to less than 4 minutes. Obviously, since many of you won’t be playing your normal instruments, I’m not expecting greatness here — I just want to see that you’ve successfully opened the door to using this approach. 

Also, feel free to modify the program any way you’d like. Obvious tweaks are to the delay and interval parameters, but you can change anything you’d like, as long as you can get it working. Looking forward to hearing what you come up with!


Submissions

Shimon Gambourg — random intervals and delays — keyboard + Kontakt

I anticipate supercollider to be a deep, deep rabbit hole. Coming from years of max and jitter I appreciated the need to finally write something down – I have managed to somehow avoid CSound in my undergrad, so thank you for the wake up call. For this week, I’ll go ahead and submit the very first piece I created using the software. Again, by doing this I essentially fight the need to self-edit and correct mistakes later…

I’ve made a very simple variation of the code, so I could have multiple outputs with their individual params (the velocities are randomized as well):

MIDIClient.init;
MIDIIn.connectAll;

~midiOut1 = MIDIOut.newByName("IAC Driver", "IAC Bus 1");
~midiOut2 = MIDIOut.newByName("IAC Driver", "IAC Bus 2");
~midiOut3 = MIDIOut.newByName("IAC Driver", "IAC Bus 3");
~midiOut4 = MIDIOut.newByName("IAC Driver", "IAC Bus 4");
~midiIn = MIDIIn.findPort("nanoKEY2", "KEYBOARD");

~interval1 = rrand(-24, 24);
~delay1 = 4.0.rand;
~interval2 = rrand(-24, 24);
~delay2 = 4.0.rand;
~interval3 = rrand(-24, 24);
~delay3 = 4.0.rand;
~interval4 = rrand(-24, 24);
~delay4 = 4.0.rand;

The code then controls a couple of kontakt instances, and you even can hear the melody every once in a while!

This is beautiful, Shimon! I gather from name of the file you sent me that you’re playing All The Things You Are? I think I can hear the bridge about 1 minute in? A very cool transformation. Personally, I’m drawn to algorithms where the response has a more obvious relationship to what I’m playing, and that’s why I usually shy away from randomness — that way I feel like I understand what the computer is doing, and I can react the way I would if I were playing with a person with whom I have an understanding. That said, what you’ve done here is beautiful, and there’s a lot to be said for introducing more chaotic elements into the mix, as you’ve done here. Great that you’ve made the code your own.

Shimon Gambourg follow up submission:

I’m attaching a more “standard” submission that has the same piece of code, but here it’s one output for five different params, so every once in a while I scramble them and get a new series as a response.

MIDIClient.init;
MIDIIn.connectAll;
~midiOut = MIDIOut.newByName("IAC Driver", "IAC Bus 1");
~midiIn = MIDIIn.findPort("PreSonus AudioBox iTwo", "AudioBox iTwo MIDI OUT");
~interval = rrand(-12, 12);
~delay = 1.0.rand;

MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
SystemClock.sched(~delay,{
~midiOut.noteOn(0, thisNum + ~interval, 100.rand);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay,{
~midiOut.noteOff(0, thisNum + ~interval, veloc);
});
}, srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);

MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
SystemClock.sched(~delay / 2 + 2,{
~midiOut.noteOn(0, thisNum + ~interval / 2 + 2, 100.rand);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay / 2 + 2,{
~midiOut.noteOff(0, thisNum + ~interval / 2 + 2, veloc);
});
}, srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);

MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
SystemClock.sched(~delay / 2 + 3,{
~midiOut.noteOn(0, thisNum + ~interval / 2 + 3, 100.rand);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay / 2 + 3,{
~midiOut.noteOff(0, thisNum + ~interval / 2 + 3, veloc);
});
}, srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);

MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
SystemClock.sched(~delay / 3 + 4,{
~midiOut.noteOn(0, thisNum + ~interval / 3 + 4, 100.rand);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay / 3 + 4,{
~midiOut.noteOff(0, thisNum + ~interval / 3 + 4, veloc);
});
}, srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);

MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
SystemClock.sched(~delay / 2 + 5,{
~midiOut.noteOn(0, thisNum + ~interval / 2 + 5, 100.rand);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay / 2 + 5,{
~midiOut.noteOff(0, thisNum + ~interval / 2 + 5, veloc);
});
}, srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);

Love this — and in particular, it’s nice to get to hear the pitches clearly. Your idea of randomizing the velocities of the notes you send out is excellent — really makes the algorithm come to life and makes the fact that the generated material is all derived from what you’re playing far less obvious. What I like about this is that on the one hand, it’s wild music; but on the other, we can clearly perceive that there’s underlying structure. This is a great example of the intersection of the mechanical and the natural in music — which is the overarching theme of this course.

Austin Zhang — Perfect 5th down, .8sec delay — EWI

Here’s just a very short improvisation using an .8 second delay and a perfect 5th down for this week. Looking forward to doing more with it.

Love what you’ve done here. You’ve managed to make the canon very clear — in the sense that both voices have clear melodies that make them distinguishable — and at the same time, the two voices work beautifully together, in excellent counterpoint. You’re even able to manage modulations, so clearly you’ve thought about the contrapuntal implications of a canon at the perfect fifth. It’s great to hear this approach on an instrument as expressive as the EWI, too. My only criticism is that I wish it had gone on for longer! Would love to hear you elaborate on this for 4 minutes. That said, this is kind of a perfect little piece of music as it stands.

Austin Zhang follow up submission:

Just an hour before class, opened the same SuperCollider project and pressed record and this came out. Played with some of the ideas from my last recording and went from there.

Thanks for sending something longer, Austin! Hearing this solidifies what I said in response to your previous track, which is that you’ve clearly spent time figuring out how the canon at the 5th can function contrapuntally. And that’s one of my favorite aspects of this project — that it forces us to examine the constraints we impose on ourselves and come up with creative solutions. I love the development that you bring to this longer version — the move to the high register towards the end nicely announces that you’re about to wrap things up. And congratulations on remaining poised and in rhythm the entire time. Beautiful track.

Maxine Troglauer — Changing intervals with external delay — keyboard + Logic

Thanks for last week, it was – frankly- quite overwhelming, but I got everything to work and it’s fun after all!
I was trying to find some solution to write a piece of code that would make a steady, increasing delay or an automatic frequency shift every second or something like that, but I couldn’t figure that out. 
I tried out DelayN, DelayC, FreqShift and things like ~decay, ~muffle, but none of that really affected the sound. 
I think I just don’t know where to actually place those things in the chord.
Nevertheless, attached is my improv – the feedback and delay was luckily in the sound preset from Logic that I used. 

I’m so glad you pushed through the overwhelming feelings from last week, because I love what you’ve done here. Most importantly, I can hear you having genuine fun with this new instrument you’ve made, and I can hear how it’s leading you to make clear and decisive choices. There’s also a remarkable amount of development in this improvisation, with clear beginnings and endings. When you take a pause to change the interval of the algorithm, it’s really satisfying when the next section starts; we can feel that a breath has been taken, and we can also feel that the new section is fundamentally different from what preceded it, because the new interval gives it a palpably different flavor. I love how the interaction of the SuperCollider algorithm with the Logic delay gives the whole thing a rhythmic identity that ties it together. Overall, a strong piece of music, congratulations.

Brandon Choi — random intervals — EWI

Here’s the code I used for the piece:

//call first interval and delay amounts
~interval1 = 5;
~delay = 0.1667;
MIDIFunc.noteOn({
arg veloc, num;
//introduce the spice (plus 1 because we don’t want 12.rand == 0)
var spicyNote = num + 12.rand + 1;

//ensure we’re receiving midi
 "midi received ".postln; num.postln;

//schedule .noteOn()’s
 SystemClock.sched(~delay,{
       ~midiOut.noteOn(0, num + ~interval1, veloc);
    //ensure midi was sent
       "midi sent ".postln; (num + ~interval1).postln;
 });
 SystemClock.sched(~delay + 0.1667,{
       ~midiOut.noteOn(0, spicyNote, veloc);
    //ensure spicy midi was sent
       "midi sent ".postln; spicyNote.postln;

 });

//ensure we don’t go deaf
 MIDIFunc.noteOff({ |veloc, num, chan, src|
       SystemClock.sched(~delay,{
            ~midiOut.noteOff(0, num + ~interval1, veloc);
       });SystemClock.sched(~delay + 0.1667,{
            ~midiOut.noteOff(0, spicyNote, veloc);
       });
 },  srcID: ~midiIn.uid, noteNum: num).oneShot;

//ensure without any doubt we don’t go deaf
}, srcID: ~midiIn.uid);

The general idea is to generate two evenly spaced notes (implying a triplet) from the underlying original. The second will always be a fourth, but the third is a random note between a minor second and an octave. I felt that this could open up some harmonic and rhythmic doors, but at the tight rate of the ~delay variable and the wild variance of the interval, the notes tend to go by too fast to really react or make sense of. I’m sure that with practice I could do this with more efficacy. Looking back on the code, it seems that I could have forgone the ~delay variable for simply .167 and .3 for the respective .noteOn() and .noteOff() functions.

I feel pretty good about the piece, I tried to move between 3, 4, and 5 fluidly, and I think this comes across. This sort of practice definitely highlights the weakness in my time and rhythm though! Plus, I found a serendipitous major triad at the end that I just had to end on.

Really great job with this, Brandon. You’ve discovered one of my favorite aspects of this approach, which is that it can bring up some pretty intense rhythmic challenges! You say that it highlights weaknesses in your time, but I think you’re doing pretty well here on that front, addressing the challenge head on. The time is clear most of the time, and even the virtuosic micro-rhythms are mostly strong, and I know from experience that they’re tough to pull off. As you point out, it’s something that will get better with practice. It really tests whether every note is in its right place, doesn’t it? Your idea of having a two-note delay, with the first note deterministic and the second one random, is very cool, and creative, too. You could’ve just written the two delays as ~delay and ~delay*2, that way you could easily change the tempo on the fly by changing your ~delay global variable. The one thing I would encourage you to explore is using the full range of your EWI’s expressive output, and also to try using some more natural sounds, so it sounds less like an 80s video game. It’s interesting — the sounds we use have such a strong influence on the affect of the music, even if the note content stays the same. Great job!

Gavon Mitchell — 5ths — keyboard

I did my improv at 5ths. I cannot play piano well but basically just tried my very best to improv over this bass line.

Love this, Gavon! You do two interesting things here: first, you decided to have the volume level of the algorithmic response quite a bit lower than what you’re playing, which gives it a feeling of echoing what you’ve played, rather than being an independent voice; and second, you really honored the rhythmic possibilities of this approach. Given that piano isn’t your main instrument, I think you did a remarkable job of creating something that holds up musically. It even has a satisfying ending! Congratulations on making this approach work.

Henry Sherris — octave — keyboard

I chose to do a canon at the octave inspired by your all the things you are. I’ve been playing around with the parameters of the decay this week and intervals but in the end kept it simpler with 0.5 decay and the octave. I found it easier to play in time with yourself / past ideas if you keep a steady bassline or rhythm which I tried to do even if some areas sound dissonant as result. The first into part is an improvisation to help get into the rhythm/response, and the second an improv of the all of me melody.

Thanks for this, Henry. I love how I can feel you discovering the algorithm as you go. I particularly like what happens about 50 seconds in, when the rhythm really starts to lock in. I’d be interested in hearing you do this with the response at the same volume level as what you’re playing, so that the two voices sound equal — like a call and response. Congrats on making this challenging approach work for yourself.

Jacob Leibowitz — various intervals — keyboard

Thank you so much for teaching this amazing course. I really enjoyed it and learned a lot. I hope that at some point you offer a continuation on this. Below is the code I used in my improvisation. I just ran everything at once and played with it. I know the code is insanely messy and redundant, but it worked!

(
MIDIClient.init;
MIDIIn.connectAll;
~midiIn = MIDIIn.findPort("Digital Piano", "Digital Piano");
~midiOut = MIDIOut.newByName("LoopBe Internal MIDI", "LoopBe Internal MIDI");
MIDIFunc.noteOn({
arg veloc, num;
"veloc ".post;veloc.postln;
"num ".post;num.postln;
~midiOut.noteOn(0, num + 7, veloc);
~midiOut.noteOff(0, num +7, veloc);
},
srcID: ~midiIn.uid);
);

(
MIDIFunc.noteOn({
arg onVeloc, onNum;
~midiOut.noteOn(0, onNum, onVeloc);
MIDIFunc.noteOff({
arg offVeloc, offNum;
~midiOut.noteOff(0, offNum, offVeloc);
},  srcID: ~midiIn.uid, noteNum: onNum).oneShot;
}, srcID: ~midiIn.uid);
)

(
~interval1 = 5;
~interval2 = 7;
~delay = 0.3;
MIDIFunc.noteOn({
arg veloc, num;
var thisNum = num;
"midi received ".postln; num.postln;
SystemClock.sched(~delay,{
~midiOut.noteOn(0, thisNum + ~interval1, veloc);
});
SystemClock.sched(~delay + 0.3,{
~midiOut.noteOn(0, thisNum + ~interval2, veloc);
});
MIDIFunc.noteOff({ |veloc, num, chan, src|
SystemClock.sched(~delay,{
~midiOut.noteOff(0, thisNum + ~interval1, veloc);
});SystemClock.sched(~delay + 0.3,{
~midiOut.noteOff(0, thisNum + ~interval2, veloc);
});
},  srcID: ~midiIn.uid, noteNum: thisNum).oneShot;
}, srcID: ~midiIn.uid);
)

(
MIDIClient.init;
MIDIIn.connectAll;
~midiOut = MIDIOut.findPort (
~midiIn = MIDIIn.findPort("DKV-M4", "Port1");
MIDIFunc.noteOn({
arg veloc, num;
"veloc ".post;veloc.postln;
"num ".post;num.postln;
});
)

Love this, Jacob! You have a way, probably because you’re a composer, of improvising in a very clear, structured way. I hear you being patient with ideas and listening hard as the algorithm reacts. You give us a satisfying ending, too. Yes, your code could be simpler, and hopefully we’ll get a chance to dive into this more in the future, but the fact that you’ve succeeded in making compelling and fresh music using this approach makes me happy. My one comment is that I feel like this would work even better if the sound you chose had some kind of evolution when a note is held. Could be as simple as a decay, or some kind of timbral change — but because you’re using held notes, I think they’d be even more impactful if the sound wasn’t so static. Anyway, congrats on a lovely track.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published.