Go Down

Topic: clap detect (Read 11104 times) previous topic - next topic


As RetroLefty hinted You need to be tracking the envolope of the sound rather that the raw frequency's them self's. You can get ic's for graphic eq's that split the audio into 7 baud's i think and output 7 envolope curves. You could read these on the analog input pin's.
You would want to use all 7. Some analysis using audio editing software and spectrograms of clapping should shed some light on the subject. By comparing this data to the frequency's of your eq ic output's you should be able to come up with an algorithm that at least starts to cut out the frequency's that your not interested in and analyses the envolope curves independently. It will never be 100% though.


The link below shows a screen shot of the audio waveform (44.1K sampling rate, "Amadeus" software for Mac) of me saying "Hello" and me clapping twice, with close ups showing (selected in blue) eactly 20 ms from both. Note the zero crossings, places where the curve crosses the zero line. I count about 22 in the 20 ms of hello, and about 80 in 20 ms of a clap. Here is the link:


Note that if you had 20 crossings in 20 ms, that would be about 1 per ms or a tone of about 1,000 Hz, which is about where my voice is. The voice signal has lots of high frequency overtones in it, but as you can see, these manifest as small wiggles on the main almost-sine wave. In other words, the main frequency is very powerful, the overtones weak. Whereas a clap products LOTS of high frequency noise all strong. Easy to see in the pictures.

Zero crossings is a gross approximation of the pitch. Reference:

Also, zero crossings is computationally easy. I suspect something like the following might work. It doesn't store anything in an array and is computationally easy. It monitors for 10 ms, if the clap was very short it might miss it, so might have to reduce the times thru the for loop and all other numbers. I have not tried this code, just suggesting something like it might work... Good luck!

Code: [Select]

void waitForClap() {

bool clap;
  int amp,prev_amp;

  prev_amp = analogRead(0) - 512;
  #define sign(x) ( (x>=0) ? +1 : -1 )
  int zeroCrossings=0;
  int highAmp=0;
  // I estimate this loop will go about 8KHz, thus 80 times is 10 ms
  for (int i=0; i<=80; i++)
    amp = analogRead(0) - 512;
    if (sign(amp) != sign(prev_amp)) zeroCrossings++;
    if (abs(amp) > 300) highAmp++;
  clap = (highAmp > 15 && zeroCrossings > 20); // all numbers subject to experimentation!
     while (clap = false);


What you are asking for, to be able to distinguish between a loud voice and a loud clap is something beyond the capabilities of an Arduino, at least in my opinion.

So I would look at doing a fast fourier transform and the look for the different spectrum between a clap and the human voice.

Go Up