Josef Korbel
Josef Korbel

Reputation: 1208

Smoothing signal from microphone - Hearthbeat

I'm working on project using oximeter.I want to smooth it out so I can use it for calculating hearthbeat. I'm gathering raw data from microphone , I put them in new array, lets say, sData[].

Signal is really crazy and jumps all over the plot as expected, so i tried smoothing it using moving average. So my main code looks something like this.

writeAudioDataToFile(); 
for (int a = 0; a < sData.length; a++) {  
      tempAvg += Math.abs(sData[a]);
      if (a % numberOfSamplesAveraged == 0) { //Average from x samples
            if (myIndex > SAMPLE_SIZE - 1) {
                myIndex = 0;
            }
            tempAvg = tempAvg / numberOfSamplesAveraged;
            if (tempAvg > 500) {
                newDataArray[myIndex] = 500;
            }else{
                newDataArray[myIndex] = tempAvg;
     } //This is suppose to clear the high peaks.

     Log.d("isRecording - Average from " + numberOfSamplesAveraged + " numbers.", "newDataArray[" + myIndex + "] = " + newDataArray[myIndex]);
     tempAvg = 0;
     myIndex++;
   }
}
notifier.notifyObservers();
Log.d("Notifier", "Notifier Fired!");

Thread.sleep(20); //Still experimenting with this value

It looks so messy, but the plot (I'm using AndroidPlot btw) looks good but it is so inaccurate so I can't calculate the hearthrate from it. It has so much "Bounce" in "high" state. I found on internet that some kind of filter (Maybe IIR filter) will do the job. So i just wanna ask you guys how can i achieve a nice smooth chart? Is IIR filter the way to go? Is there any free applet/lib to smoothen it out? This is my first question here so I'm really sorry if it is badly written. If you will need any more information to help me, just ask. Here is a picture how my chart looks like now.

http://oi62.tinypic.com/2uf7yoy.jpg // Cant post images im new here.

This is a lucky one though. I need smoother output.

Upvotes: 1

Views: 523

Answers (1)

Rafał P
Rafał P

Reputation: 252

Noises, which occur at measurement, have high frequency. You should filter your signal, that is you should retain low frequency part of signal and suppress high frquency part of signal. You can do it, making a low-pass filter. It could be, for example, first-order inertial model. I suggest make a pass-band till ~~10 kHz, since people hear sound from 2 kHz to 20 kHz. Then appriopriate sample time is 0,0001 sec (0,1 ms). Discrete model has following equation:

y[k] = 0.9048*y[k-1] + 0.09516*u[k-1],

where u is a measured vector (directly from microphone, input in our filter), and y is a vector you want to analyze (so output from our filter).

As you can see,, you can calculate a sample number 1, and you can just assign 0 to the sample number 0. After all, you can try to plot y vector.

Upvotes: 2

Related Questions