We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Average of maxSpectrum[i] , for BeatDetection
Page Index Toggle Pages: 1
Average of maxSpectrum[i] , for BeatDetection (Read 1931 times)
Average of maxSpectrum[i] , for BeatDetection
Oct 15th, 2009, 12:55am
 
hi,

i would like to get an average from my lineIn, for the last 1.5 seconds.
when i do it with milis(), i have to reset the avregae every 1500msec, so the average starts new every 1500msec. this is not what i want.

how can i get a real average of my lineIn ??

mfg maik

Ps. sorry for my bad english----> Deutsch ^^ Huh
Re: Average of maxSpectrum[i] , from last 1.5 seconds
Reply #1 - Oct 15th, 2009, 2:03am
 
even if you're reading from the device every 1.5 seconds, you can store a buffer of the values received so far, using a global array.

You'll have to be careful not to exceed your array length...in the long run, it may be worth creating a temperature class and a Vector to hold a resizable amount of them.  But for now, I'd try something like this:

Code:
float[] storedVals = new float[1000];
int arrayPosition = 0;

void setup(){
//etc
}

void draw(){
//get value from lineIn, store at arrayPosition:
storedVals[arrayPosition] = the new value;
if (arrayPosition > 0) println (getAverage());
// ^ nip that divide-by-0 in the bud...
arrayPosition++; // add 1 to the array position
}

float getAverage(){
float total = 0;
float valueNum = 0;
for (int i=0;i<arrayPosition;i++){
total += storedVals[i];
valueNum ++;
}
float avg = total / valueNum;
return avg;
}
Re: Average of maxSpectrum[i] , from last 1.5 seconds
Reply #2 - Oct 15th, 2009, 3:27am
 
Wouldn't that give an average of all readings thus far though  That's not always what's needed.  The Arduino site has some handy code for smoothing out noise on analog inputs and IIRC the approach is relatively easy to implement in Processing.
Re: Average of maxSpectrum[i] , from last 1.5 seconds
Reply #3 - Oct 15th, 2009, 6:14am
 
hi,

i've made my own BeatDetection with this, and it work's very well.
but after reaching the arrayposition maximum, it begins from from the start Wink
and that's not good Shocked, you can see it in the sketch Shocked

mfg maik

Code:
import processing.opengl.*;
import krister.Ess.*;

AudioInput myInput;
FFT myFFT;

int bufferSize;
int averages;
float[] storedVals = new float[128];
float[] storedVals2 = new float[128];
int arrayPosition = 0;
int arrayPosition2 = 0;
float a;
float b;
float avg;
float a2;
float b2;
float avg2;
float eRadius;

void setup(){
size(400, 400);
Ess.start(this);
bufferSize = 2048;
averages = 512;
myInput=new AudioInput(bufferSize);
myFFT = new FFT(averages);
myFFT.updateMultiplier=.8;
myFFT.smooth=true;
myInput.start();
ellipseMode(CENTER_RADIUS);
eRadius = 20;
}

void draw(){
background(0);
//smooth();
for (int i=0; i<averages/2; i++) {
float temp=max(0,height-(myFFT.maxSpectrum[i])*256);
rect(i*4,temp,3,height-temp);
}
//a= ((myFFT.maxSpectrum[1]+myFFT.maxSpectrum[2]+myFFT.maxSpectrum[3]+myFFT.maxSpectrum[4]+myFFT.maxSpectrum[5])/2*width);
a= ((myFFT.maxSpectrum[1])*height*2);
//b= ((myFFT.spectrum[1]+myFFT.spectrum[2]+myFFT.spectrum[3]+myFFT.spectrum[4]+myFFT.spectrum[5])*width);
b= ((myFFT.maxSpectrum[2])*height*2);
//avg = (avg < 50) ? 50 :avg ;
//avg2 = (avg2 < 50) ? 50 :avg2 ;
stroke(0,255,0);
line(0,height-b,400,height-a);
stroke(255,0,0);
line(0,height-avg,400,height-avg2);

float c = map(eRadius, 20, 80, 60, 255);
fill(60, 255, 0, c);
ellipse(width/2, height/2, eRadius, eRadius);
eRadius *= 0.5;
if ( eRadius < 20 ){
eRadius = 20;
}



//get value from lineIn, store at arrayPosition:
storedVals[arrayPosition] = b;
if (arrayPosition > 0) getAverage();
// ^ nip that divide-by-0 in the bud...
arrayPosition++; // add 1 to the array position
if (arrayPosition == 128){
arrayPosition = 1;
}
//get value from lineIn, store at arrayPosition:
storedVals2[arrayPosition2] = a;
if (arrayPosition2 > 0) getAverage2();
// ^ nip that divide-by-0 in the bud...
arrayPosition2++; // add 1 to the array position
if (arrayPosition2 == 128){
arrayPosition2 = 1;
}
if(((b>avg)&&(avg>70))||((a>avg2)&&(avg2>70)))
{
eRadius = 80;
//delay(30);
}
}
public void audioInputData(AudioInput theInput) {
myFFT.getSpectrum(myInput);
}
float getAverage(){
float total = 0;
float valueNum = 0;
for (int i=0;i<arrayPosition;i++){
total += storedVals[i];
valueNum ++;
}
float m = map((total / valueNum), 0, height, 2,1);
avg = total / valueNum*m;
println (m);
return avg;
}
float getAverage2(){
float total2 = 0;
float valueNum2 = 0;
for (int i=0;i<arrayPosition2;i++){
total2 += storedVals2[i];
valueNum2 ++;
}
float m2 = map((total2 / valueNum2), 0, height, 2,1);
avg2 = total2 / valueNum2*m2;
;
//println (avg);
//println(valueNum2);
return avg2;
}

void stop() {
Ess.stop(); // When program stops, stop Ess too
super.stop();
}



Re: Average of maxSpectrum[i] , from last 1.5 seconds
Reply #4 - Oct 15th, 2009, 9:59am
 
WOW  Shocked

thanks  blindfish,

that works perfekt! with Kai Tracid Cool
this is what i have tried.  Wink

now i have an other problem, everytime i detect a beat, i will not detect another beat for 200-300msec.
how can i do this, without "delay(300); ??
i won't stop the whole sketch for 300msec.

mfg maik

Code:
import processing.opengl.*;
import krister.Ess.*;

AudioInput myInput;
FFT myFFT;

int bufferSize;
int averages;

float a;
float b;
float avg;
float a2;
float b2;
float avg2;
float eRadius;
float total;
float total2;
int numReadings = (100);
int index = 0;
float[] readings= new float[numReadings];
float average = 0;    
int numReadings2 = (100);
int index2 = 0;
float[] readings2= new float[numReadings2];
float average2 = 0;  
boolean [] beat;


void setup(){
 size(400, 400);
 Ess.start(this);
 bufferSize = 2048;
 averages = 512;
 myInput=new AudioInput(bufferSize);
 myFFT = new FFT(averages);
 myFFT.updateMultiplier=.8;
 myFFT.smooth=true;
 myInput.start();
 ellipseMode(CENTER_RADIUS);
 eRadius = 20;
 for (int thisReading = 0; thisReading < numReadings; thisReading++)
   readings[thisReading] = 0;  
 for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
   readings2[thisReading2] = 0;
 beat = new boolean[1];
}

void draw(){
 background(0);
 smooth();
 a= ((myFFT.spectrum[0])*height*2);
 b= ((myFFT.spectrum[1])*height*2);
 stroke(0,0,255);
 line(0,height-b,400,height-a);
 stroke(0,255,0);
 line(0,height-avg,400,height-avg2);
 stroke(255,0,0);
 line(0,height-avg/2.1,400,height-avg2/2.1);
 float c = map(eRadius, 20, 80, 60, 255);
 fill(60, 255, 0, c);
 eRadius = beat[0] ? 80 : eRadius > 20 ? eRadius - .1 : 20;
 ellipse(width/2, height/2, eRadius, eRadius);
 eRadius *= 0.5;
 if ( eRadius < 20 ){
   eRadius = 20;
 }
 average();
 average2();
 if((b>avg)&&(avg>100)&&(!beat[0])){
   beat[0] = true;
   delay(20);
 }
 else if((a>avg2)&&(avg2>100)&&(!beat[0])){
   beat[0] = true;
   delay(20);
 }
 else {
   beat[0] = false;
 }
}
public void audioInputData(AudioInput theInput) {
 myFFT.getSpectrum(myInput);
}
float average(){
 total= total - readings[index];  
 readings[index] = b;
 total= total + readings[index];
 index = index + 1;  
 if (index >= numReadings)  
   index = 0;  
 float m = map((total / numReadings), 0, height, 2,1);
 avg = total / numReadings*m;  
 return   avg;
}

float average2(){
 total2= total2 - readings2[index2];  
 readings2[index2] = a;
 total2= total2 + readings2[index2];
 index2 = index2 + 1;  
 if (index2 >= numReadings2)  
   index2 = 0;  
 float m2 = map((total2 / numReadings2), 0, height, 2,1);
 avg2 = total2 / numReadings2*m2;  
 return   avg2;
}
void stop() {
 Ess.stop();
 super.stop();
}




Re: Average of maxSpectrum[i] , for BeatDetection
Reply #5 - Oct 15th, 2009, 2:57pm
 
Glad to be of service; though all I did was remember that I'd used that code for a similar purpose in the past Smiley

I haven't got the krister package installed so can't try your code.  What's the purpose of the delay  If you just want to add a pause before executing something you could look into using millis.  Actually it's a shame there isn't some equivalent to setInterval() in Processing; though I guess it might not be too difficult to create something like that...

Kai Tracid   Huh
Re: Average of maxSpectrum[i] , for BeatDetection
Reply #6 - Oct 15th, 2009, 3:47pm
 
Re: Average of maxSpectrum[i] , for BeatDetection
Reply #7 - Oct 16th, 2009, 11:39am
 
@ BenHem & blindfish

Kai Tracid is a DJ, and i have tested it with his Music  Grin

@ all

can anybody tell me why the beatdetection has a delay??
what's the problem with my code??

mfg maik

Code:
import processing.opengl.*;
import krister.Ess.*;
import controlP5.*;

AudioInput myInput;
FFT myFFT;
ControlP5 controlP5;
int bpmMin=120;
int bpmMax=140;
int bufferSize;
int averages;
int msecMin;
float msecMax;
float eRadius;
long p=500;
int q=500;
float a;
float b;
float a2;
float b2;
float avg;
float avg2;
float avg3;
float avg4=500;


float total;
float total2;
float total3;
float total4;

int numReadings = (100);
int numReadings2 = (100);
int numReadings3 = (1000);
int numReadings4 = (200);

int index = 0;
int index2 = 0;
int index3 = 0;
int index4 = 0;

float average = 0;
float average2 = 0;
float averageAll = 0;
float average4 =500;

float[] readings= new float[numReadings];
float[] readings2= new float[numReadings2];
float[] readings3= new float[numReadings3];
float[] readings4= new float[numReadings4];

boolean [] beat;
int mydelay;
int milidif;
int time ;
float Volume = 1;

void setup(){
size(400, 400);
controlP5 = new ControlP5(this);
controlP5.addRange("range",100,160,120,140,0,0,400,30);
controlP5.addKnob("Volume",0.01,2,1,180,40,40);

PFont fontB = loadFont("Georgia-Bold-48.vlw");
textFont(fontB, 15);
time = 0;
milidif = 500;
mydelay = 300;
Ess.start(this);
bufferSize = 2048;
averages = 512;
myInput=new AudioInput(bufferSize);
myFFT = new FFT(averages);

myInput.start();
ellipseMode(CENTER_RADIUS);
eRadius = 20;
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
readings2[thisReading2] = 0;
for (int thisReading3 = 0; thisReading3 < numReadings3; thisReading3++)
readings3[thisReading3] = 0;
for (int thisReading4 = 0; thisReading4 < numReadings4; thisReading4++)
readings4[thisReading4] = 0;
beat = new boolean[1];
}

void draw(){
background(0);
smooth();
int q = int(avg4);

fill(255);
text(q+" msec",10, 50);
text((60000/q)+" BPM",320, 50);
a();
b();
time = millis();

milidif=time-mydelay;

stroke(0,0,255);
line(0,height-b,400,height-a);
stroke(0,255,0);
line(0,height-avg,400,height-avg2);
stroke(255,0,0);
line(0,height-avg/2.1,400,height-avg2/2.1);
stroke(255,255,0);
line(0,height-avg3,400,height-avg3);

eRadius = beat[0] ? 80 : eRadius > 20 ? eRadius - 2 : 20;
float c = map(eRadius, 20, 80, 60, 255);
fill(60, 255, 0, c);
ellipse(width/2, height/2, eRadius, eRadius);
if ( eRadius < 20 ){
eRadius = 20;
}
average();
average2();
averageAll();
averageBPM();
beat();

fill(0);
msecMin = 60000/bpmMin;
msecMax = 60000/bpmMax;
/*println("msecMin : "+msecMin);
println("bpmMin : "+bpmMin);
println("msecMax : "+msecMax);
println("bpmMax : "+bpmMax);*/
println(Volume);
}
void controlEvent(ControlEvent theControlEvent) {
if(theControlEvent.controller().name().equals("range")) {
// min and max values are stored in an array.
// access this array with controller().arrayValue().
// min is at index 0, max is at index 1.
println(theControlEvent.controller().arrayValue());
bpmMin = int(theControlEvent.controller().arrayValue()[0]);
bpmMax = int(theControlEvent.controller().arrayValue()[1]);
}

}
public void audioInputData(AudioInput theInput) {
myFFT.getSpectrum(myInput);
}
boolean beat() {
if((b>avg)&&(b>avg3)&&(!beat[0])&&(milidif>msecMax)){
beat[0] = true;
mydelay=time;
p = milidif>msecMin ? msecMin : milidif;




}
else if((a>avg2)&&(a>avg3)&&(!beat[0])&&(milidif>msecMax)){
beat[0] = true;
mydelay=time;
p = milidif>msecMin ? msecMin : milidif;



}
else {
beat[0] = false;
}
return beat[0];
}
float a(){
a= ((myFFT.spectrum[0])*height*2*Volume);
return a;
}
float b(){
b= ((myFFT.spectrum[1])*height*2*Volume);
return b;
}
float average(){
total= total - readings[index];
readings[index] = b;
total= total + readings[index];
index = index + 1;
if (index >= numReadings)
index = 0;
float m = map((total / numReadings), 0, height/3*2, 3.5,.9);
m = m<1 ? 1 : m;
avg = total / numReadings*m;
return avg;
}

float average2(){
total2= total2 - readings2[index2];
readings2[index2] = a;
total2= total2 + readings2[index2];
index2 = index2 + 1;
if (index2 >= numReadings2)
index2 = 0;
float m2 = map((total2 / numReadings2), 0, height/3*2, 3.5,.9);
m2 = m2<1 ? 1 : m2;
avg2 = total2 / numReadings2*m2;

return avg2;
}

float averageAll(){
total3= total3 - readings3[index3];
readings3[index3] = b+a;
total3= total3 + readings3[index3];
index3 = index3 + 1;
if (index3 >= numReadings3)
index3 = 0;
float m3 = map((total3 / numReadings3), 0, height/3*2, 3,1);
m3 = m3<1 ? 1 : m3;
avg3 = total3 / numReadings3*m3;
return avg3;
}

float averageBPM(){
total4= total4 - readings4[index4];
readings4[index4] = p;
total4= total4 + readings4[index4];
index4 = index4 + 1;
if (index4 >= numReadings4)
index4 = 0;

avg4 = total4 / numReadings4;

return avg4;
}
void stop() {
Ess.stop();
super.stop();
}





Re: Average of maxSpectrum[i] , for BeatDetection
Reply #8 - Oct 17th, 2009, 12:17pm
 
My best guess is that expensive routines like text() and println() are holding you back a bit...I turned those, and smooth(), and the controlP5 output off, put "frameRate(999);" in setup() to break the 60 FPS limit, and it seems responsive to snapping.  But it doesn't seem to grab the next beat until the circle is finished shrinking...should the circle be popping back to max size if a beat is detected while shrinking?
Re: Average of maxSpectrum[i] , for BeatDetection
Reply #9 - Oct 19th, 2009, 12:52am
 
hi BenHem,

i've do what you whant Smiley

and it look's better.  but now my BeatDetection is to nervous.
i will try more averages.
what do you mean with Quote:
".I turned those, ......controlP5 output off"
??

Quote:
But it doesn't seem to grab the next beat until the circle is finished shrinking...should the circle be popping back to max size if a beat is detected while shrinking?


the next BeatDetection is grab after the timedifference iss grater then the maxTime iss reached!! it's necessary to choke double BeatDetection  Wink
the circle iss only an indication for me.
the BeatDetection is in this code
Code:
boolean beat() {
 if((a>avg)&&(a>avg3)&&(!beat[0])&&(milidif>msecMax)){
   beat[0] = true;
   mydelay=time;
   p = milidif>msecMin ? msecMin : milidif;




 }
 else if((b>avg2)&&(b>avg3)&&(!beat[0])&&(milidif>msecMax)){
   beat[0] = true;
   mydelay=time;
   p = milidif>msecMin ? msecMin : milidif;



 }else if((c>avg4)&&(c>avg3)&&(!beat[0])&&(milidif>msecMax)){
   beat[0] = true;
   mydelay=time;
   p = milidif>msecMin ? msecMin : milidif;




 }
 else {
   beat[0] = false;
 }
 return  beat[0];
}

  • avg, avg2 & avg4 = average off the 3 fft-signal's over 1.5 sec.
  • avg3 = average off all 3 fft signals together over round 10 sec.
  • mydelay = last time stored after BeatDetection
  • milidif=time-mydelay;
  • msecMax = is the time of the maximum BPM, to choke double BeatDetection
  • p = only for calculating the BPM, it's min range iss set by msecMin.
    to not get to high msec in the calculation.
  • a, b & c = the incomming audio signal of the 3 fft bands


regards maik
Re: Average of maxSpectrum[i] , for BeatDetection
Reply #10 - Oct 19th, 2009, 7:49am
 
hey maik,
Re: what I meant: I just // commented out:
• all the controlP5 items in setup()
• all lines with text();
• all lines with println();
and put noSmooth(); in, instead of smooth();  -- should be a tiny difference for drawing a single circle, but...
Hope you solve the nervousness, or someone else has a solution -- I have had trouble avoiding jitter with audio input, while still remaining sensitive to intentional quick beats or notes, also...
Page Index Toggle Pages: 1