I am trying to code audio signal processing software in java.

Purpose: It will use audio signal processing library to filter out noise from the raw PCM based input (.wav) of heartbeat recording.

Steps involved

  1. Select input .wav file.
  2. Apply Low Pass filter at 33 Hz.
  3. Apply High Pass Filter at 2 Hz.
  4. Apply Amplification with Max Gain.
  5. Store back it as .wav file

There are many C++ library which will cover most of the requirement. But looking for Java for this particular project. Need input from Audio Signal Processing engineers for their input if these steps will be sufficient to able to hear the heartbeats. Also please let me know which order of filtering and which window will be most effective in this scenario. enter image description here

Input is taken from


  • $\begingroup$ lop~, hop~, and bp~ use first order filters. They will still let through a lot of the out of band signals. If you are using pd-extended, then you should have some better filters available. There are butterworth filters of various orders available - they look like this: lp10_butt~ (lowpass butterworth, 10th order.) The number gives the order, so you can do hp4_butt~ for a 4th order filter. Bessel and Chebyshev filters are available the same way: lp4_bess~ or lp4_cheb~ - but remember that Chebysheb can cause a lot of ringing that can cause the pauses between beats to be covered up. $\endgroup$
    – JRE
    Commented Aug 21, 2014 at 8:04
  • $\begingroup$ Just uploaded new pd with butter-worth low pass and high pass filter of order 10, I am delaying the signal and then limiting it for normalization. $\endgroup$ Commented Aug 21, 2014 at 18:22
  • $\begingroup$ Looks good. Have you tried it out? $\endgroup$
    – JRE
    Commented Aug 21, 2014 at 18:31
  • $\begingroup$ I played a music but that too sounded like a beats. Will try with my real input and check the result. I really appreciate your input. Wouldn't be possible with out it. Thanks $\endgroup$ Commented Aug 21, 2014 at 18:50
  • $\begingroup$ Tried with the above design, there are lot of ringing and also it is not at all clear. Need to make amplify the signal to make the output audible. Is there a way to amplify the signal without distorting it? $\endgroup$ Commented Aug 22, 2014 at 3:06

2 Answers 2

  1. Your low pass should be higher - probably 40 or so.
  2. Your high pass can be higher - around thirty
  3. Your gain should be variable else you will amplify it into distortion - what you want is called normalisation. You will need to find the maximum volume of your signal and calculate a scaling factor that will bring this up to full scale. (Say full scale is 1.0 and your maximum value is 0.01 then multiply all samples by 100.)

When I experiment with heart sounds, I find the beat itself to be around 34Hz - I usually do a band pass from 30 to 40 in order to isolate just the beat.

If you do this, you will have a clean recording of ONLY the heartbeat. If all you want is to count heartbeats or listen to them you will be fine. If you need to listen for heart defects or other things, then you will need to change the parameters. You will need higher frequencies and a wider bandwidth for those types of things.

One other thing you need to consider: 30 to 40 Hz doesn't really come through headphones and ears all that well. Even when you isolate the hearbeat and amplify it to full scale, it is still hard to hear. Earphones will attenuate it some, and your ears even more so.

As to actually doing the filtering:

  1. You can use IIR filters at higher orders to isolate the heart sounds. Avoid using chebyshev filters, though. The "ring" badly and can make one beat "smear" into the next.
  2. If you use an FIR, you may want to downsample first. It depends on your sampling rate. If your sampling rate is high (say the typical 44100) then an FIR than can bandpass something around 30Hz will have to be VERY long. If you downsample to 1000 Hz, then shorter filters can be used. You could get away with maybe 100 taps at 1000Hz. Downsampling consists of doing a low pass filter to remove everything above half of your new sampling rate, then "throwing away" a lot of your samples - downsampling by two would throw away every second sample, downsampling by 4 keeps one out of four samples.

When I do audio in Java, I usually import libpd, and use pd to develop the actually processing stuff. Then the same pd "patch" can be used with libpd in the java programm. pd libpd

The order in which you apply the filters (for your bandpass) shouldn't matter.

  • $\begingroup$ Thank you very much for the explanation, I was looking at pd lib earlier but gave up because lack of documentation. Other lib I was looking at was tarsosDSP, but don't know if that is tested as much as libPD. Can you please direct me to some good documentation to learn about libpd. Appreciate your help. $\endgroup$ Commented Aug 19, 2014 at 15:22
  • $\begingroup$ There is sample code for using libpd with Java here: github.com/libpd/libpd/tree/master/samples/com/noisepages/… - this is also included with the source code distribution of libpd. $\endgroup$
    – JRE
    Commented Aug 20, 2014 at 6:49
  • $\begingroup$ Thank you very much for the reference, I have started making my first attempt for making above solution to work, which I have attached to the question. Your input will be very useful, please email me your comments. $\endgroup$ Commented Aug 21, 2014 at 3:35

I think you're mixing up things here.

Acoustically, 2 Hz is inaudible, and 33 Hz is barely audible. The audible range is 20 Hz to 20.0000 Hz. Heartbeats are somewhere between 40 BPM and 180 BPM, so 0.7 Hz to 3 Hz. So your filter seems to match neither well.

Now the main challenge here is exactly what "noise" you have to filter. For medical purposes, some sounds are clinically relevant which to laymen sound like noise. But if you just need to count the beats, you don't care about noise at all - just determine the envelope, resample it to 100 Hz or so, pass several seconds to an FFT, done.

  • 1
    $\begingroup$ Heart beats occur at a rate of 40 to 180 BPM (0.7Hz to 3Hz) - that is true. However, if you have ever listened to one (or analysed it with an FFT) you would know that it is composed of bursts of 34Hz tones. So, for a heart rate of 90 BPM, you have short bursts of 34Hz sound occurring every 1.5 Seconds. $\endgroup$
    – JRE
    Commented Aug 19, 2014 at 10:20
  • $\begingroup$ @JRE: That is entirely my point: the 34 Hz is audible, but above the 33 Hz cut-off for the low-pass. And the 90 BPM is below the cutoff of 2 Hz (120 BPM). So why amplify the sounds between 2 Hz and 33 Hz? That just doesn't make sense whatsoever. You'd want a band-stop filter, not a band-pass. $\endgroup$
    – MSalters
    Commented Aug 19, 2014 at 11:56
  • $\begingroup$ You want a band pass from around 30 to 40Hz. That passes the 33 to 34 Hz of the beat and allows enough bandwidth. The BPM of the heartrate itself is only of interest in determining the needed bandwidth of the bandpass. If you allow plus or minus more than3Hz, then you have enough bandwidth - so, use 30 Hz to 40 hz bandpass. $\endgroup$
    – JRE
    Commented Aug 19, 2014 at 12:00
  • $\begingroup$ @JRE: That's a good solution if the only noise problem is noise outside the 30-40 Hz band. But if you have occasional spike noise uncorrelated to the BPM, then those spikes will still have components between 30 and 40 Hz, and that might interfere with beat detection. As I said, you can't eliminate noise unless you understand the noise characteristics. $\endgroup$
    – MSalters
    Commented Aug 19, 2014 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.