Arduino Piano code
by leah
Code for the capacitive sensing piano shown in this video:
Arduino Code
#include
<CapSense.h
>
const int NUMBER_OF_SENSORS = 10;
CapSense* sensorDefinitions [NUMBER_OF_SENSORS];
#define ARRAYX 1
#define ARRAYY NUMBER_OF_SENSORS
int sensorArray [ARRAYX][ARRAYY];
CapSense note1 = CapSense(3,2);
CapSense note2 = CapSense(3,4);
CapSense note3 = CapSense(6,5);
CapSense note4 = CapSense(6,7);
CapSense note5 = CapSense(9,8);
CapSense note6 = CapSense(9,10);
CapSense note7 = CapSense(12,11);
CapSense note8 = CapSense(A1,A0);
CapSense note9 = CapSense(A1,A2);
CapSense note10 = CapSense(A4,A3);
long start, sensor;
int i, j;
void setup()
{
sensorDefinitions[0] = ¬e1;
¬e2
sensorDefinitions[1] = ;
¬e3
sensorDefinitions[2] = ;
¬e4
sensorDefinitions[3] = ;
¬e5
sensorDefinitions[4] = ;
¬e6
sensorDefinitions[5] = ;
¬e7
sensorDefinitions[6] = ;
¬e8
sensorDefinitions[7] = ;
¬e9
sensorDefinitions[8] = ;
¬e10
sensorDefinitions[9] = ;
Serial.begin(9600);
}
void loop()
{
start = millis();
for (i=0;i<NUMBER_OF_SENSORS;i++)
>
{
sensor = (*sensorDefinitions[i]).capSense(10);
if (sensor 100)
sensorArray[0][i]=1;
else
sensorArray[0][i]=0;
}
sendArray();
}
void sendArray ()
{
for (i=0;i<ARRAYX;i++)
<
{
for (j=0;jARRAYY;j++)
{
Serial.print(sensorArray[i][j]);
Serial.print('\t'); //tab character
}
Serial.print('\n'); //new line c
}
Serial.print('!');
}
Processing Code
/**
* Adopted by High-Low Tech from SinePiano by Dan Ellis, dpwe@ee.columbia.edu
*/
import ddf.minim.analysis.*;
import ddf.minim.*;
import ddf.minim.signals.*;
import processing.serial.*;
Minim minim;
AudioOutput out;
Serial myPort;
int ARRAYX = 1;
int ARRAYY = 10;
int [][] sensorArray = new int[ARRAYX][ARRAYY];
int [][] sensorArrayOld = new int[ARRAYX][ARRAYY];
int [][] noteArray = new int[ARRAYX][ARRAYY];
//note definitions
int C4= 262;
int D4= 294;
int E4= 330;
int F4= 349;
int G4= 392;
int A4= 440;
int B4= 494;
int C5= 523;
int D5= 587;
SineWave mySine;
MyNote newNote;
void setup()
{
size(512, 200, P3D);
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil('!');
minim = new Minim(this);
out = minim.getLineOut(Minim.STEREO);
noteArray[0][0]=C4; //z
noteArray[0][1]=D4; //x
noteArray[0][2]=E4; //c
noteArray[0][3]=F4; //v
noteArray[0][4]=G4; //b
noteArray[0][6]=A4; //n
noteArray[0][7]=B4; //m
noteArray[0][8]=C5; //,
noteArray[0][9]=D5; //.
}
void draw()
{
background(0);
stroke(255);
// draw the output waveforms, so there's something to look at
for(int i = 0; i < out.bufferSize() - 1; i++)
{
float x1 = map(i, 0, out.bufferSize(), 0, width);
float x2 = map(i+1, 0, out.bufferSize(), 0, width);
line(x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
line(x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
}
}
void serialEvent (Serial myPort) {
String inString = myPort.readStringUntil('!');
String[] incomingArrayRows = splitTokens(inString, "\n");
for (int i=0;i<ARRAYX;i++)
<
{
String[] incomingArrayEntries = splitTokens(incomingArrayRows[i], "\t");
for (int j=0;jARRAYY;j++)
<
{
sensorArrayOld[i][j] = sensorArray[i][j];
sensorArray[i][j]=int(incomingArrayEntries[j]);
}
}
float pitch = 0;
for (int i=0;iARRAYX;i++)
<
{
for (int j=0;jARRAYY;j++)
{
if (sensorArray[i][j]>0 & (sensorArray[i][j]!=sensorArrayOld[i][j]))
{
pitch = noteArray[i][j];
newNote = new MyNote(pitch, 0.3);
}
}
}
}
void stop()
{
out.close();
minim.stop();
super.stop();
}
class MyNote implements AudioSignal
{
private float freq;
private float level;
private float alph;
private SineWave sine;
MyNote(float pitch, float amplitude)
{
freq = pitch;
level = amplitude;
sine = new SineWave(freq, level, out.sampleRate());
alph = .9; // Decay constant for the envelope
out.addSignal(this);
}
void updateLevel()
{
// Called once per buffer to decay the amplitude away
level = level * alph;
sine.setAmp(level);
// This also handles stopping this oscillator when its level is very low.
if (level < 0.01) {
out.removeSignal(this);
}
// this will lead to destruction of the object, since the only active
// reference to it is from the LineOut
}
void generate(float [] samp)
{
// generate the next buffer's worth of sinusoid
sine.generate(samp);
// decay the amplitude a little bit more
updateLevel();
}
// AudioSignal requires both mono and stereo generate functions
void generate(float [] sampL, float [] sampR)
{
sine.generate(sampL, sampR);
updateLevel();
}
}