Now With 20% More SuperCollider

I’ve been doing a lot of travel this year — as probably almost everyone reading this knows, I’ve relocated for the most part to North Carolina for work. It’s been almost equal parts fun and hard (that’s what she said…), and it’s also provided something very useful in that it’s been an intense stress-test for my gear. Every time I fly back and forth I learn a little more about how it would actually hold up in a situation like touring, and how likely I am to have gear issues at any given performance — and I’ve had enough technical difficulties that the conclusion I’ve come to is that, unfortunately, trying to use my eurorack for any kind of touring or long-term live performance solution is just not sustainable.

The timing worked out well, because this came up right around the time that I had another encounter with SuperCollider. I hadn’t heard of the program before Moogfest earlier this year, where I met a gentleman named Scott Lindroth who had created a SuperCollider and Arduino-based sound installation. I asked him two million questions (aka my standard “this is amazing!!” routine — I feel bad for anyone who gets subjected to it) and he showed me some of his work with it.

It was really exciting to me because while I’ve played around with Max a little bit, I haven’t been able to get into it; I find the user interface extremely annoying. I would infinitely rather write code than sit there twiddling with virtual patch cables. So I immediately liked the idea, but the learning curve was so steep that I couldn’t bring myself to get started; I downloaded the software and didn’t open it for four months.

Author & Punisher, again…

Then I went to see Author & Punisher in Baltimore, because of course I did. The opener was a man named Jeff Carey who had built a setup that was eerily similar to mine — a few keys that he would press with his left hand and a joystick that he manipulated with his right. The catch was that all his sound generation was done with SuperCollider. He sounded fantastic (seriously, check him out! https://www.youtube.com/watch?v=OU_wDXlNDGQ ) and it gave me the impetus I needed to finally get rolling with SC.

But of course it’s not that easy

As it turns out, SuperCollider works the best on OSX. And I hate Macs. I cracked open the software and after building a few basic synths, just waves with some kind of filter, I started trying to get my gloves hooked up.

And ran headlong into a brick wall. It turns out the “SerialPort” class isn’t compatible with Windows, and while I’m a pretty good developer, my firmware skills are pretty lacking, so even though the software is open source I wouldn’t even know where to start writing my own. I’ve spent the last couple of days trying to find a workaround (at one point even trying to dual boot Ubuntu because that seemed easier (it wasn’t)). This is the sort of challenge where I’m straining at the very limits of what other people have written about, which is always a weird feeling.

PureData, OSC, and Firmata

Getting the Scalar Glove hooked up was relatively easy. For the Arduino all I did was upload StandardFirmata. To get it into SC I needed to install PureData, but I was able to download a pd file directly to process the pin data and output it as an OSC message and send it internally as a udp package. In SuperCollider I only needed to run this:

s = Server.local;
s.boot;

n=NetAddr("127.0.0.1", 57120);
OSCFunc.trace(true);

With that I was able to view the data coming in from the sensors connected to my analog input pins. A little string processing on SuperCollider’s end and I had a viable value that I could use to control the parameter of a synth.

Almost done, right? Just needed to hook up the vector glove?

…not so fast:

I2C and Arduino Mega

There were two additional complications with getting the vector glove hooked up that made me want to pull my hair out. The first is that the vector glove is based on an Adafruit BNO055 chip, which communicates over i2c rather than directly into the analog read pins like the scalar glove does; the second is that the vector glove is using an Arduino Mega 2560 rather than an Uno like the scalar glove. StandardFirmata doesn’t support Arduino Mega, and most solutions involved sending only single pieces of data — a single sensor value versus a whole bunch of them like the BNO055 provides. So the solution I’d created for the scalar glove was totally irrelevant for getting the vector glove to work.

I was able to figure it out with the help of a kind person on the internet who had created a serial_print class (https://github.com/alexdrymonitis/Arduino_Pd). I needed to use the serial_print_extended version because pd-extended was needed to support one of the extensions I was using, but it was able to work after I got it set up. It’s simply talking over the Serial port:

sc_2

The Arduino code is basic, too. I just process the sensor data in some rough ways (normalizing the X, Y and Z values to 0-255) and then print it out as a list of newline-delimited, space-separated values. Code here: https://drive.google.com/open?id=0B7dYt-6F7tqWY3JqVm5walRUQXM

And it worked! I was able to get both gloves talking at once over the same port, and process the data out. The SuperCollider code isn’t very pretty (ugh, so much repetition) but I’ll clean it up later:

s = Server.local;
s.boot;

n = NetAddr("127.0.0.1", 57120);
OSCFunc.trace(false);

var i, m, r, p, x, y, z, l_x, l_y, l_z;
f = { | msg,
 time,
 addr |
 if (msg[0] == '/vector') {
 if (msg[1] != nil) {
 x = msg[1].round(1);
 "X: %; ".postf(x);
 };
 if (msg[2] != nil) {
 y = msg[2].round(1);
 "Y: %; ".postf(y);
 };
 if (msg[3] != nil) {
 z = msg[3].round(1);
 "Z: %; ".postf(z);
 };
 if (msg[4] != nil) {
 l_x = msg[4].round(0.1);
 "X_Acc: %; ".postf(l_x);
 };
 if (msg[5] != nil) {
 l_y = msg[5].round(0.1);
 "Y_Acc: %; ".postf(l_y);
 };
 if (msg[6] != nil) {
 l_z = msg[6].round(0.1);
 "Z_Acc: %;\n".postf(l_z);
 };
 };
 if (msg[0] != '/status.reply') {
 if (msg[1] == 0) {
 i = msg[2].round(0.01);
 "I: %; ".postf(i);
 };
 if (msg[1] == 1) {
 m = msg[2].round(0.01);
 "M: %; ".postf(m);
 };
 if (msg[1] == 2) {
 r = msg[2].round(0.01);
 "R: %; ".postf(r);
 };
 if (msg[1] == 3) {
 p = msg[2].round(0.01);
 "P: %;\n".postf(p);
 };
 }
};
thisProcess.addOSCRecvFunc(f);

thisProcess.removeOSCRecvFunc(f);
n.disconnect;

 

Signal processing is 9/10ths of the law

The hard part is done. Now all I need to do is write some kickass synths…

Honestly, I’m pretty happy with this project. Version 1 of the gloves took a few months, version 2 took a few weeks, version 3 took a few days — at this rate I’ll be inventing the Borg by this time next year.

Resistance is futile.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s