Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque condimentum eros sed vehicula rhoncus. Maecenas vel molestie est. Sed quis turpis sapien. Donec vel dignissim augue, vel maximus velit. Pellentesque eget pretium tellus, nec aliquet purus.

Information
Email
Instagram
Twitter
SANTIPAB SOMBOON

Creative Technologist // Filmmaker //
Aspiring Data Scientist //

INSTALLATIONS
BirdSpace
Haijaii
Quisque Vita Est
Time Tunnel
Euismod Faucibus
Quam Lora
Curabitur
Mauris Facili
Nam Facibu Est

Information


Email
Instagram

Brief:
This is a light-based instrument that you can play by waving your arms around. It's made from two coffee cups, each of which sounds a different pitch. Light levels determine volume and vibrato. To measure the amount of light, there is a photocell in the bottom of each cup. The Arduino gathers in data from the photocells, and sends it to the laptop, which then uses miniAudicle (a musical programming language) to synthesize notes.

The physical build is crucial to providing an interesting and different experience. By hiding the wires in the box, I want to make people focus on the sound. Furthermore, any change in size or material of the cup should generate different sounds.

For future iterations, I would like the cups to generate natural instead of digital sounds. I would also do some user testing to get a sense of user interaction. For this iteration however, it could benefit people with impaired vision relying on auditory feedback. It could be a medicine cabinet, where the user receives a different sound ping depending on the cup selection.

Video:


Pictures:


Schematic:


Arduino code:
float analogPins[] = {0, 1, 2, 3, 4, 5};

void setup()
{
Serial.begin(9600);
}


void loop()
{
for (int i = 0; i < 6; i++)
{
int val = analogRead(analogPins[i]);
Serial.print(val);
Serial.print(" ");
}
Serial.println();
}

miniAudicle code:
SerialIO.list() @=> string list[];

for(int i; i < list.cap(); i++)
{
chout = list.cap())
{
cherr int triggerThresh;
300.0 => float range;

Gain g;
g.gain(0.3);
PRCRev rev;
rev.mix(0.5);

g => dac;

SinOsc vibs[numPins];
SinOsc vib;
vib => blackhole;
5 => vib.freq;
5 => float baseVibFreq;

fun void calibrate() {

20 => int numLaps;
5 => int throwAways;

for (0 => int i; i < throwAways; i++) {
cereal.onLine() => now;
cereal.getLine() => string line;
}
5::ms => now;

for (0 => int lap; lap < numLaps; lap++) {
cereal.onLine() => now;
cereal.getLine() => string line;
if(line$Object != null) {
StringTokenizer tok;
tok.set(line);

for (0 => int i; i < numPins; i++) {
// Fill history with default values
Std.atoi(tok.next()) => int pinVal;

for (0 => int j; j < historyLength; j++) {
pinVal => pinHistory[i][j];
}
// Store a 1D base vals array, too.
pinVal + baseVals[i] => baseVals[i];

}

}
}
for (0 => int i; i < numPins; i++) {
>;
baseVals[i] / numLaps => baseVals[i];
>;
>;
}
>;

}

fun void setup() {
// Setup stuff
for (0 => int i; i < numPins; i++) {
gains[i].gain(0.5);
vibs[i] => blackhole;
5 => vibs[i].freq;
envs[i] => g;
for (1 => int j; j oscs[i][j-1].freq;
//(Std.mtof((36 + i) * 2)) * (j * 0.5) => oscs[i][j-1].freq;
oscs[i][j-1].freq() => baseFreqs[i][j-1];
oscs[i][j-1] => envs[i]; //=> g;
}
baseFreqs[i][0] => sinOscs[i][0].freq;
sinOscs[i][0] => envs[i];
Std.mtof(notes[i] - 24) => sinOscs[i][1].freq;
sinOscs[i][1] => envs[i];
0 => baseVals[i];

dac.chan(i);
}
}

0 => int bufferIndex;
fun void processLine(StringTokenizer tok) {
for (0 => int i; i < numPins; i++) {
Std.atoi(tok.next()) => int newVal;
newVal => pinHistory[i][bufferIndex];

int oldVal;
if (bufferIndex == 0) {
pinHistory[i][historyLength - 1] => oldVal;
}
else {
pinHistory[i][bufferIndex - 1] => oldVal;
}

Std.abs(newVal - baseVals[i]) => int diff;


if (diff >= triggerThresh) {
// Is ON!
(diff - triggerThresh) / range => float newGain;
baseVibFreq + (newGain * 2) => vibs[i].freq;
//>;
//diff / range => float newGain;
envs[i].target(newGain / 3.0);
if (newGain / 3.0 > 1) {
envs[i].target(1.0);
}
envs[i].duration(1::ms);
envs[i].keyOn();
1::ms => now;
}
else {
// Is OFF!

// If we WERE on before, do an envelope’d end
if (Std.abs(oldVal - baseVals[i]) >= triggerThresh) {
envs[i].target(0);
envs[i].keyOff();
}
}

} // End looping over cups.

// Advance buffer index
bufferIndex + 1 => bufferIndex;
if (bufferIndex >= historyLength) {
0 => bufferIndex;
}

}

fun void viber() {
while (true) {
for (0 => int i; i < numPins; i++) {
for (0 => int j; j < oscsPerPin; j++) {
(vibs[i].last() * 5) + baseFreqs[i][j] => oscs[i][j].freq;
}
}
0.001::second => now;
}
}


setup();
calibrate();

spork ~ viber();

while(true)
{
cereal.onLine() => now;
cereal.getLine() => string line;
if(line$Object != null) {
chout