Magical Blanket. no more boundary between music and body movement
by greatjudy
We are intrigued by the interaction between human and music. This project suggests a combination of body postures and generated acoustic effects.
For this final project, we created a blanket of matrix of 16 pressure sensors, each sensor consists of two pieces of conductive fabrics, with one piece of velostat and two layers of light net fabrics.
To connect the sensors, we used two set of parallel and perpendicular conductive threads, and using one diode for each of the sensor. As a result, we used only 4 analogue input to read the numbers of the whole matrix. The design of the blanket is inspired from traditional Chinese paper-cut of zodiac and Polish woodcut. To construct cover layer, we used the white canvas as the base. We glued them first with iron and sewed them around with sewing machine. For those patterns, we laser cut the red cotton fabric and glued them on top of the white canvas.
For the processing, many improvements could be done. For this version, we tried sound and to create different pitches with the sensor. We used Promide library to process the data from the sensors and transform it into different set of sound track with different wavelength( pitch).We used a midi machine connected to computer and created sound of various musical instruments and electric effects. To visualize it, we created several circles based on the position of the sensor, its diameter is based on the data from the sensor, that means the higher pressure it receives, the strong the signal it produces, the bigger it is.
Video: http://www.youtube.com/watch?v=HReYU7DG5MY
Code 1:
import processing.serial.*;
import promidi.*;
Sequencer sequencer;
Serial myPort; // The serial port
//variables for collecting and storing information
int ARRAYX = 4;
int ARRAYY = 4;
int [][] sensorArray = new int[ARRAYX][ARRAYY];
//variables for drawing information on the screen
int [][] volArray = new int[ARRAYX][ARRAYY];
int spacing = 100;
PFont font;
Track track;
MidiIO midiIO;
MidiOut test;
void setup () {
//set the window size:
size(400, 400);
//initialize the font variables
//background(255);
// font = loadFont(“Interstate-Bold-12.vlw”);
//textFont(font);
// list all the available serial ports
println(Serial.list());
// open the appropriate port
myPort = new Serial(this, Serial.list()[2], 9600);
// don’t generate a serialEvent() until you get an exclamation mark character
myPort.bufferUntil(‘!’);
// set inital background:
sequencer = new Sequencer();
//MidiIO
midiIO = MidiIO.getInstance();
midiIO.printDevices();
midiIO.closeOutput(1);
//MidiOut
test = midiIO.getMidiOut(1,3);
test.sendProgramChange(new ProgramChange(20));
//Track
track = new Track(“one”, test);
track.setQuantization(Q._1_32);
}
void draw () {
background(255);
//loop through the array
for (int i=0;i<ARRAYX;i++)
{
for (int j=0;j<ARRAYY;j++)
{
//calculate the position for each entry so that print out is approximately centered onscreen
int xPosition = width/2-((ARRAYX-1)*spacing/2)+j*spacing;
int yPosition = height/2-((ARRAYY-1)*spacing/2)+i*spacing;
//draw the array entries on the screen
// text(sensorArray[i][j], xPosition, yPosition);
// noFill();
smooth();
stroke(255,55);
ellipse(xPosition,yPosition, sensorArray[i][j]/20, sensorArray[i][j]/20);
}
}
drawCircles();
}
void serialEvent (Serial myPort) {
//store a batch of data into variable “inString”
//batches are separated by exclamation mark characters
String inString = myPort.readStringUntil(‘!’);
//split the data into rows (rows separated by new line characters)
String[] incomingArrayRows = splitTokens(inString, “\n”);
//loop through all of the rows
for (int i=0;i<ARRAYX;i++)
{
//split each row into entries (entries separated by tab characters)
String[] incomingArrayEntries = splitTokens(incomingArrayRows[i], “\t”);
//loop through all of these entries
for (int j=0;j<ARRAYY;j++)
{
//store entries in the “sensorArray” variable
sensorArray[i][j]=int(incomingArrayEntries[j]);
//print the entries to the terminal, separated by tab characters
print(sensorArray[i][j]);
print(‘\t’);
}
//print a new line after each row
println();
}
//print a new line after each batch of data
println();
makesound();
}
void drawCircles()
{
for(int i=0;i<ARRAYX;i++)
{
for(int j=0;j<ARRAYY;j++)
{
//
if (sensorArray[i][j]>500)
{
//calculate the position for each entry so that print out is approximately centered onscreen
int xPosition = width/2-((ARRAYX-1)*spacing/2)+j*spacing;
int yPosition = height/2-((ARRAYY-1)*spacing/2)+i*spacing;
delay(20);
noStroke();
smooth();
fill(#AF0000, 50);
ellipse(xPosition,yPosition, sensorArray[i][j]/5, sensorArray[i][j]/5);
}
}
}
}
void mousePressed(){
if(mouseButton == LEFT) {
makesound();
sequencer.start();
}
else sequencer.stop();
}
boolean flag = false;
void makesound()
{
for(int i=0;i<ARRAYX;i++)
{
for(int j=0;j<ARRAYY;j++)
{
if (sensorArray[i][j]>300)
{
//volArray[i][j] = int (sensorArray[i][j]/1024*127);
volArray[i][j] = 127;
}
else
volArray[i][j] = 0;
}}
track.addEvent(new Note(60, volArray[0][0],40), 0);
track.addEvent(new Note(60, 0,40), 1);
track.addEvent(new Note(62, volArray[0][1],40), 2);
track.addEvent(new Note(62, 0,40), 3);
track.addEvent(new Note(64, volArray[0][2],40), 4);
track.addEvent(new Note(64, 0,40), 5);
track.addEvent(new Note(65, volArray[0][3],40), 6);
track.addEvent(new Note(65, 0,40), 7);
track.addEvent(new Note(67, volArray[1][0],40), 8);
track.addEvent(new Note(67, 0,40), 9);
track.addEvent(new Note(69, volArray[1][1],40), 10);
track.addEvent(new Note(69, 0,40), 11);
track.addEvent(new Note(71, volArray[1][2],40), 12);
track.addEvent(new Note(71, 0,40), 13);
track.addEvent(new Note(72, volArray[1][3],40), 14);
track.addEvent(new Note(72, 0,40), 15);
track.addEvent(new Note(74, volArray[2][0],40), 16);
track.addEvent(new Note(74, 0,40), 17);
track.addEvent(new Note(76, volArray[2][1],40), 18);
track.addEvent(new Note(76, 0,40), 19);
track.addEvent(new Note(77, volArray[2][2],40), 20);
track.addEvent(new Note(77, 0,40), 21);
track.addEvent(new Note(79, volArray[2][3],40), 22);
track.addEvent(new Note(79, 0,40), 23);
track.addEvent(new Note(81, volArray[3][0],40), 24);
track.addEvent(new Note(81, 0,40), 25);
track.addEvent(new Note(83, volArray[3][1],40), 26);
track.addEvent(new Note(83, 0,40), 27);
track.addEvent(new Note(84, volArray[3][2],40), 28);
track.addEvent(new Note(84, 0,40), 29);
track.addEvent(new Note(86, volArray[3][3],40), 30);
track.addEvent(new Note(86, 0,40), 31);
Song song = new Song(“test”, 100);
song.addTrack(track);
sequencer.setSong(song);
sequencer.setLoopStartPoint(0);
sequencer.setLoopEndPoint(512);
sequencer.setLoopCount(-1);
if(!flag){
sequencer.start();
flag = true;
}
}
Code 2:
import processing.serial.*;
import promidi.*;
Sequencer sequencer;
Serial myPort; // The serial port
//variables for collecting and storing information
int ARRAYX = 4;
int ARRAYY = 4;
int [][] sensorArray = new int[ARRAYX][ARRAYY];
//variables for drawing information on the screen
int [][] volArray = new int[ARRAYX][ARRAYY];
int spacing = 100;
PFont font;
Track track;
MidiIO midiIO;
MidiOut test;
void setup () {
//set the window size:
size(400, 400);
//initialize the font variables
//background(255);
// font = loadFont(“Interstate-Bold-12.vlw”);
//textFont(font);
// list all the available serial ports
println(Serial.list());
// open the appropriate port
myPort = new Serial(this, Serial.list()[2], 9600);
// don’t generate a serialEvent() until you get an exclamation mark character
myPort.bufferUntil(‘!’);
// set inital background:
sequencer = new Sequencer();
//MidiIO
midiIO = MidiIO.getInstance();
midiIO.printDevices();
midiIO.closeOutput(1);
//MidiOut
test = midiIO.getMidiOut(1,3);
test.sendProgramChange(new ProgramChange(20));
//Track
track = new Track(“one”, test);
track.setQuantization(Q._1_32);
}
void draw () {
background(255);
//loop through the array
for (int i=0;i<ARRAYX;i++)
{
for (int j=0;j<ARRAYY;j++)
{
//calculate the position for each entry so that print out is approximately centered onscreen
int xPosition = width/2-((ARRAYX-1)*spacing/2)+j*spacing;
int yPosition = height/2-((ARRAYY-1)*spacing/2)+i*spacing;
//draw the array entries on the screen
// text(sensorArray[i][j], xPosition, yPosition);
// noFill();
smooth();
stroke(255,55);
ellipse(xPosition,yPosition, sensorArray[i][j]/20, sensorArray[i][j]/20);
}
}
drawCircles();
}
void serialEvent (Serial myPort) {
//store a batch of data into variable “inString”
//batches are separated by exclamation mark characters
String inString = myPort.readStringUntil(‘!’);
//split the data into rows (rows separated by new line characters)
String[] incomingArrayRows = splitTokens(inString, “\n”);
//loop through all of the rows
for (int i=0;i<ARRAYX;i++)
{
//split each row into entries (entries separated by tab characters)
String[] incomingArrayEntries = splitTokens(incomingArrayRows[i], “\t”);
//loop through all of these entries
for (int j=0;j<ARRAYY;j++)
{
//store entries in the “sensorArray” variable
sensorArray[i][j]=int(incomingArrayEntries[j]);
//print the entries to the terminal, separated by tab characters
print(sensorArray[i][j]);
print(‘\t’);
}
//print a new line after each row
println();
}
//print a new line after each batch of data
println();
makesound();
}
void drawCircles()
{
for(int i=0;i<ARRAYX;i++)
{
for(int j=0;j<ARRAYY;j++)
{
//
if (sensorArray[i][j]>500)
{
//calculate the position for each entry so that print out is approximately centered onscreen
int xPosition = width/2-((ARRAYX-1)*spacing/2)+j*spacing;
int yPosition = height/2-((ARRAYY-1)*spacing/2)+i*spacing;
delay(20);
noStroke();
smooth();
fill(#AF0000, 50);
ellipse(xPosition,yPosition, sensorArray[i][j]/5, sensorArray[i][j]/5);
}
}
}
}
void mousePressed(){
if(mouseButton == LEFT) {
makesound();
sequencer.start();
}
else sequencer.stop();
}
boolean flag = false;
void makesound()
{
//test.sendProgramChange(new ProgramChange(20));
for(int i=0;i<ARRAYX;i++)
{
for(int j=0;j<ARRAYY;j++)
{
if (sensorArray[i][j]>300)
{
//volArray[i][j] = int (sensorArray[i][j]/1024*127);
if(volArray[i][j] == 0){
volArray[i][j] = 127;
test.sendNote(new Note(i*4+j+60, 127, 1000));
}
}
else{
volArray[i][j] = 0;
test.sendNote(new Note(i*4+j+60, 0, 0));
}
}
}