Thursday, October 26, 2006

Midterm (Parts I-VIII, Abridged)

Kazoodles : Networked Interactive Kazoo Trio


I-III. The process (Brainstorming to Forming)

Let me first say, even in hindsight, that it was wonderful working with Chris and Meredith; we were able to discuss, delegate, and disagree without much friction or wasted time. We were able to settle on a general area of interest almost right off the bat: updating some kind of musical instrument into the digital age. We were also able to decide with some conviction on the kazoo, as it was possibly the most un-modern, un-digital instrument we could think of. Plus, kazoo's are fun.

It took us considerably longer to refine our ideas into something that was both conherent in vision and limited in scope enough that we could at least conceive of a process to complete it. Thus, we settled on the idea of a multiple kazoo orchestra that would somehow interact with a patch through MAZ/MSP to make sounds.

From there we had several more questions to answer, some of which we struggled with throughout most of the developmet of the project, such as:
Should the sounds be pretty, or artsy?
What sort of sensors should we put in the kazoos? (What will fit, give the most dynamic but predictable readings, be relatively cheap, etc.)
What will the kazoo's look like when they're done?
How to we ensure that the user will understand what they can/should/should not do?
How in the hell to we get MAX and ARDUINO to understand eachother?

And so, we embarked.

IV-VII. Design, Develop, Debug, Repeat.

We decided to approach the developmet by divide and conquer. Meredith was in charge of the actual wiring, and the look and feel for the kazoo's. Chris and I, being musicians, worked on getting the Arduino to talk to MAX, and for MAX to understand and sort the data that it was getting. As Chris was the only one with previous experience in MAX, and I felt more comfotable writing the Arduino code, we ended more or less splitting the duties that way, although we all made substantial contributions to all facets of the project.

Our first main challenge was to get MAX and Arduino talking to each other. Although we had not yet made a final decision on which sensor we were going to use, we knew that they would be analog in nature, to give a more sensitive reflection of musical input. We decided to do most of the development testing using potentiometers, as they were ready at hand, and could give fiarly consistent readings over the whole of the possible value range we were looking at (i.e. 0-1024).

Using the serial object from MAX we able to read a stream of data coming in from the pot. However, all we were receiving was a non-sensical loop of numbers. We then, (after some time) realized not only that we needed to send the data over in BYTE form instead of DEC, but that MAX would only be able to use values of 1-255. In other words, we had to scale down the output values from Arduino. Moreover, we had to find a way to help MAX recognize the split between data streams, since we were using multiple analog inputs, all with the same possible ranges and we wanted each kazoo to control a different aspect of one main sound wave (progamming the kazoo's to harmonize with eachother reliably would've taken a few more weeks of work).

Out solution was to scale: we scaled down the number of analog kazoo's down to two; thus we could divide the acceptble range of values (0-255) into two distinct streams (0-127 and 128-255) which would then be easy to split in MAX. Easy to split in MAX means easy to manipluate distinct aspects of the sound.

Since we had decided on the setup of a master kazoo (equipped with a small mic) as the master kazoo controlling the main pitch along with the two analog kazoo's changing the wave, we had decided to adapt a classic vocoder patch in MAX. (A vocoder is basically a voice-disortion effect) We were then able to hook up each analog data stream into one of the aspects of the vocoder patch. This worked technically, but resulted in totally random and mostly unlistenable noise.

So, we had to find a way to limit the possible sound variations that the sensors could produce. After a few a tries, Chris came up with the idea of taking a few (three) presets that we liked, setting one as the default (i.e. no analog input), and the other two presets as the possible range of the two analog sensors. This required a lot of further setup, and our Max patch was starting to look pretty intimidating (which I rather liked, since I kind of understood it) but we were able to do it, and so we were ready to go, after some fine tuning.

As for the Arduino side of it, we had relatively little trouble getting the code set up to test out the max patch with potentiometers. We had a significantly longer process coding after we switched from pots to thermistors and added PWM'ing led's to each kazoo.

After some debugging, both with code and with the breadboard, the kazoo's were working, at least technically. The issue was that the thermistors were not responding as we had predicted to human breath. Actually, they weren't respoding predicably to anything. Our mistake for not testing the sensors before installing them in the kazoo's. Fortunately, we were able to further limit the MAX patch to allow for some fairly randominput from the thermistors, without descending into total chaos.

Here's the final code, in case you're wondering:

int potPin = 0; // Analog input pin that the pot (therm) is attached to
int potValue = 0;
int potPin2 = 1;
int potValue2 = 0;

int led1 = 11; // w/ analog in 0
int led2 = 10; //w / analog in 1
int led3 = 9; // for mic led


void setup() {

// initialize serial communications at 9600 bps:
Serial.begin(9600);
}

void loop() {
potValue = analogRead(potPin); // pot1 (0-127)
analogWrite (led1, potValue/4); //light led 1 w/ the therm

// Serial.println (potValue, DEC); // print pot1 value


if (analogRead(potPin) > 127) {
potValue = (analogRead(potPin) / 8)+1;
}
else if (analogRead(potPin) <= 127) {
potValue = (analogRead(potPin) / 1) +1;
}

Serial.print (potValue, BYTE); // print pot1 value




potValue2= analogRead(potPin2); //pot2 (128-255)
analogWrite (led2, potValue2/4); //light led 2 w/ the therm

// Serial.println (potValue2, DEC); //print pot2 value

if (analogRead(potPin2) < 128) {
potValue2 = (analogRead(potPin2) + 128);
}
else if (analogRead(potPin2) >= 128) {
potValue2 = (analogRead(potPin2)/8) +128;
}

Serial.print (potValue2, BYTE); //print pot2 value

delay (10);
}



The only remaining hurdle was to get it all working at the same time; something we had continually struggled with in one form or another throughout the project. We were espcially having troubles with MAX and Arduino fighting for the serial port and crashing the Mac's in the audio lab. We spent a lot of time rebooting at attempting (unsuccessfully, as noted in our presentatnion) to figure out a reliable protocol for uploading and playing with both a mic in and the serial port engaged.

We were lucky enough of the time to keep going with the project, until we had a sound that we were all happy with. So, all we could do is cross our fingers.

Part VIII. Conclusions

While this was a time intensive project all around, and I think we came a long way, espcially in getting a reliable parcing of information from Arduino into MAX, there are few things I think we should have done differetly.
1. Test your sensors. Duh.
2/3. I think we spent too much time worrying about the actual sound, and not enough time on whether we could consistently get it to work. Our first priority once all the pieces were in place should have been to ensure that we could get a reliable result. If you take a great picture and don't develop the film, it's not such a great picture, is it?
3. Although this is relative to how much time we had, I think we should have done more educated research into what we were doing. A little digging around in the beginning would have saved us a lot of time and frustration in the end.

Having said all of that, I am happy with the way things came out. Were it not for the serial issues, we indeed achieved our goal, which, considering we had almost no clue as to how were we going to do it, is a pretty good accomplishment. I also learned quite a bit, espcially since this was my first time dealing with MAX/MSP.
All in all, I'm very happy with it, and very happy to move on.