EEG code
In the EEG code for sampling with a sound card I found that i was unable to actually run the program as a section seems to be missing components. I am new to coding overall and everything that I have tried has so far failed.

If some one could help me correct the issue in the code above that would be great and really appreciated.
I had to rewrite a couple of lines like NUM_CHANNELS isn't defined and the array myArray is one dimensional not 2 so I removed the myArray[i][j] and made it myArray[j] any mention of it. added AudioIN in to actualy get the microphone input. Removed timeSignal( and a couple of others here is my revised code /* Reading and Visualizing EEG Data
- by Christian Henry.
- Reads in EEG data through the microphone input of the
- computer, then displays the signal in time, its frequency
- components, and then averages of frequencies that estimate
- the concentration of different brain waves. *
- For reference, the frequency bars are ordered/classified as
- follows: *
- 1 - blue -------- delta
- 2 - blue/purple - theta
- 3 - purple ------ alpha
- 4 - purple/red -- low beta
- 5 - dark red ---- mid beta
- 6 - red --------- high beta
- This sketch will measure all brain waves, from 0 - 30 Hz. It does
- best, however, measuring alpha waves across the occipital lobe.
- To view this function, play the program, click the window to
- make sure its in "focus", and hit the "a" key to bandpass the alpha
- waves only. The alpha wave bar is the 3rd one (purple), and should
- increase in height by 2-3x when you close your eyes and relax
- (you'll see it for a second or two after you open your eyes, before it
- averages back down).
- / /* One issue: when taking the FFT of the data, it seems as if the frequency bands have a bandwidth of 1.33 instead of 1, as 60Hz noise peaks out at band 45. This is worked around by using the scaleFreq parameter, which is used frequently. / import processing.serial.; import ddf.minim.; import ddf.minim.signals.; import ddf.minim.analysis.; import ddf.minim.effects.;
//Important constants that may need to be changed. float timeScale = 50; //scales the amplitude of time-domain data, can be changed static float normalScale = 50; static float alphaScale = 100; static float timeLength = 60; static int freqAvgScale = 50; //does same for averages of frequency data static int alphaCenter = 12; static int alphaBandwidth = 2; //really bandwidth divided by 2 static int betaCenter = 24; static int betaBandwidth = 2; static int NUM_CHANNELS = 1;
//Variables used to store data functions/effects. Minim minim; Serial myPort; AudioInput in; float[] timeSignal = new float[240]; FFT fft; NotchFilter notch; LowPassSP lpSP; LowPassFS lpFS; BandPass betaFilter; BandPass alphaFilter;
//Constants mainly used for scaling the data to readable sizes. int windowLength = 840; int windowHeight = 500; int FFTheight; float scaling[] = {.00202,.002449/2,.0075502/2,.00589,.008864,.01777}; int FFTrectWidth = 6; float scaleFreq = 1.33f; float timeDomainAverage = 0;
//Variables used to handle bad data int cutoffHeight = 200; //frequency height to throw out "bad data" for averaging after float absoluteCutoff = 1.5; boolean absoluteBadDataFlag; //data that is bad because it's way too far out of our desired range -- // ex: shaking your head for a second boolean averageBadDataFlag; //data that's bad because it spikes too far outside of the average for //that second -- // ex: blinking your eyes for a split second
//Constants used to create a running average of the data. float[][] averages; int averageLength = 200; //averages about the last 5 seconds worth of data int averageBins = 6; //we have 6 types of brain waves int counter = 0;
void setup() { //initialize array of averages for running average calculation averages = new float[averageBins][averageLength]; for (int i = 0; i < averageBins; i++){ for (int j = 0; j < averageLength; j++){ averages[i][j] = 0; } }
//set some drawing parameters windowLength = 840; windowHeight = 500; FFTheight = windowHeight - 200;
size(windowLength, windowHeight, P2D);
//initialize minim, as well as some filters minim = new Minim(this); minim.debugOn(); notch = new NotchFilter(60, 10, 32768); lpSP = new LowPassSP(40, 32768); lpFS = new LowPassFS(60, 32768); betaFilter = new BandPass(betaCenter/scaleFreq,betaBandwidth/scaleFreq,32768); alphaFilter = new BandPass(alphaCenter/scaleFreq,alphaBandwidth/scaleFreq,32768);
// initialize values in array that will be used for input for (int i = 0; i < 240; i++){ timeSignal[i] = 0; }
//initialize FFT fft = new FFT(256, 256); fft.window(FFT.HAMMING); rectMode(CORNERS); println(fft.getBandWidth()); }
void draw() { /*badDataFlag handles any "artifacts" we may pick up while recording the data. Artifacts are essentially imperfections in the data recording -- they can come from muscle movements, blinking, anything that disturbs the electrodes. If the program encounters a set of data that spikes out of a reasonable window (controlled by the variable cutoffHeight), it won't consider that data when computing the running average. */ absoluteBadDataFlag = false; averageBadDataFlag = false;
background(0); //make sure the background color is black stroke(255); //and that time data is drawn in white
line(0,100,windowLength,100); //line separating time and frequency data
drawSignalData();
//check for spikes relative to other data for (int i = 0; i < windowLength - 1; i++){ if (abs(in.left.get((i+1)_round(in.bufferSize()/windowLength))) > timeDomainAverage_4) averageBadDataFlag = true; }
displayText();
displayFreqAverages();
counter++; }
void keyPressed(){ if (key == 'w'){ fft.window(FFT.HAMMING); } if (key == 'e'){ fft.window(FFT.NONE); } }
void serialEvent(Serial p){ while (p.available() > 0){ shiftNtimes(timeSignal, 1);
} }
//Shifts all elements in myArray numShifts times left, resulting in the //[0-numShift] elements being pushed off, and the last numShift elements //becoming zero. Does this for all data channels. public void shiftNtimes(float[] myArray, int numShifts){ int timesShifted = 0; while (timesShifted < numShifts){ for (int j = 0; j < timeLength - 1; j++){ myArray[j] = myArray[j + 1]; } myArray[(int)timeLength - 1] = 0; timesShifted++;
} }
//Draw the signal in time and frequency. void drawSignalData(){ timeDomainAverage = 0; for(int i = 0; i < windowLength - 1; i++) { stroke(255,255,255); //data that fills our window is normalized to +-1, so we want to throw out //sets that have data that exceed this by the factor absoluteCutoff if (abs(in.left.get(i_round(in.bufferSize()/windowLength)))_timeScale/normalScale > .95){ absoluteBadDataFlag = true; fill(250,250,250); stroke(150,150,150); } //Draw the time domain signal. line(i, 50 + in.left.get(i_round(in.bufferSize()/windowLength))_timeScale, i+1, 50 + in.left.get((i+1)_round(in.bufferSize()/windowLength))_timeScale);
timeDomainAverage += abs(in.left.get(i*round(in.bufferSize()/windowLength)));
//Draw un-averaged frequency bands of signal.
if (i < (windowLength - 1)/2){
//set colors for each type of brain wave
if (i <= round(3/scaleFreq)){
fill(0,0,250); //delta
stroke(25,0,225);
}
if (i >= round(4/scaleFreq) && i <= round((alphaCenter - alphaBandwidth)/scaleFreq)-1){
fill(50,0,200); //theta
stroke(75,0,175);
}
if (i >= round((alphaCenter - alphaBandwidth)/scaleFreq) &&
i <= round((alphaCenter + alphaBandwidth)/scaleFreq)){
fill(100,0,150); //alpha
stroke(125,0,125);
}
if (i >= round((alphaCenter + alphaBandwidth)/scaleFreq)+1 &&
i <= round((betaCenter-betaBandwidth)/scaleFreq)-1){
fill(150,0,100); //low beta
stroke(175,0,75);
}
if (i >= round((betaCenter - betaBandwidth)/scaleFreq) &&
i <= round((betaCenter + betaBandwidth)/scaleFreq)){
fill(200,0,50); //midrange beta
stroke(225,0,25);
}
if (i >= round((betaCenter + betaBandwidth)/scaleFreq)+1 && i <= round(30/scaleFreq)){
fill(250,0,0); //high beta
stroke(255,0,10);
}
if (i >= round(32/scaleFreq)){
fill(240,240,240); //rest of stuff, mainly noise
stroke(200,200,200);
}
if (i == round(60/scaleFreq)){
fill(200,200,200); //color 60 Hz a different tone of grey,
stroke(150,150,150); //to see how much noise is in data
}
//draw the actual frequency bars
rect(FFTrectWidth*i, FFTheight, FFTrectWidth*(i+1), FFTheight - fft.getBand(i)/10);
}
}
//divide the average by how many time points we have timeDomainAverage = timeDomainAverage / (windowLength - 1); }
//Give user textual information on data being thrown out and filters we have active. void displayText(){ //show user when data is being thrown out text("absoluteBadDataFlag = " + absoluteBadDataFlag, windowLength - 200, 120); if (absoluteBadDataFlag == true) { println("absoluteBadDataFlag = " + absoluteBadDataFlag); println(counter); } text("averageBadDataFlag = " + averageBadDataFlag, windowLength - 200, 140); if (averageBadDataFlag == true) { println("averageBadDataFlag = " + averageBadDataFlag); println(counter); }
//and when a filter is being applied to the data text("alpha filter is " + in.hasEffect(alphaFilter), windowLength - 200, 160); text("beta filter is " + in.hasEffect(betaFilter), windowLength - 200, 180); }
//Compute and display averages for each brain wave for the past ~5 seconds. void displayFreqAverages(){ //show averages of alpha, beta, etc. waves for (int i = 0; i < 6; i++){ float avg = 0; //raw data for amplitude of section of frequency int lowFreq = 0; int hiFreq = 0;
//Set custom frequency ranges to be averaged.
if(i == 0){
lowFreq = 0;
hiFreq = 3;
fill(0,0,250);
stroke(25,0,225);
}
if(i == 1){
lowFreq = 3;
hiFreq = 7;
fill(50,0,200);
stroke(75,0,175);
}
if(i == 2){
lowFreq = alphaCenter - alphaBandwidth;
hiFreq = alphaCenter + alphaBandwidth;
fill(100,0,150);
stroke(125,0,125);
}
if(i == 3){
lowFreq = 12;
hiFreq = 15;
fill(150,0,100);
stroke(175,0,75);
}
if(i == 4){
lowFreq = betaCenter - betaBandwidth;
hiFreq = betaCenter + betaBandwidth;
fill(200,0,50);
stroke(225,0,25);
}
if(i == 5){
lowFreq = 20;
hiFreq = 30;
fill(250,0,0);
stroke(255,0,10);
}
//Convert frequencies we want to the actual FFT bands. Because of our
//FFT parameters, these happen to be equal (each band has a 1 Hz width).
int lowBound = fft.freqToIndex(lowFreq);
int hiBound = fft.freqToIndex(hiFreq);
//Scale the band number, because of the issue outlined at very beginning of
//program.
lowBound = round(lowBound/scaleFreq);
hiBound = round(hiBound/scaleFreq);
//get average for frequencies in range
for (int j = lowBound; j <= hiBound; j++){
avg += fft.getBand(j);
}
avg /= (hiBound - lowBound + 1);
// Scale the bars so that it fits our window a little better.
for (int k = 0; k < 6; k++)
{
if (i == k)
{
avg *= scaling[i]*freqAvgScale;
}
}
//update our array for the moving average (only if our data is "good")
if (absoluteBadDataFlag == false && averageBadDataFlag == false){
averages[i][counter%averageLength] = avg;
}
//calculate the running average for each frequency range
float sum = 0;
for (int k = 0; k < averageLength; k++){
sum += averages[i][k];
}
sum = sum / averageLength;
//draw averaged/smoothed frequency ranges
rect(i*width/6, height, (i+1)*width/6, height - sum);
} }
// always close Minim audio classes when you are done with them void stop() { in.close(); minim.stop(); super.stop(); }
hey @devnightmare github seemed to have mangled your code a bit and I can't seem to figure it all out, some characters have been changed into underscores and what not.
Would you mind simply pasting the code onto https://pastebin.com/ or emailing me the code?
THANKS!