# Is there an efficient algorithm to extract low frequency signal from audio with high frequency carrier?

I need to process an audio signal in an Android app. As shown in the two examples below, there is a 16kHz carrier signal and a lower frequency signal of varying frequency (0-4kHz). Does anyone know of an efficient algorithm to extract the lower frequecy signal in an Androd app?

http://mc.weatherflow.com.s3.amazonaws.com/media/IMG_03102014_135912.png

• So the lower frequency signal is centered at 16 kHz? – Jim Clay Oct 3 '14 at 16:46
• I am not sure exactly what you mean by "centered" but if you look at the included image you can visually determine that the low frequency signal is approximately 103 Hz in the top graph and about 225 Hz in the lower graph. What I need is a simple and efficient algorithm that can calculate this by looking at the full signal. – user11276 Oct 3 '14 at 17:16
• How are you calculating 103 Hz and 225 Hz from the graphs? – Jim Clay Oct 3 '14 at 17:44
• I have updated the attached image to reflect how we are calculating frequency. We are simply counting the cycles and dividing by the time to obtain the frequency. You may need to enlarge the image to see the time steps above the graph images. The two graphs are independent of each other, each containing a 16 kHz carrier (not sure if I am using this term properly), the signal is interrupted by a much lower frequency at a fairly regular interval. This lower frequency is what we would like to calculate. – user11276 Oct 3 '14 at 18:13
• So if I understand you correctly, you want to keep the low-frequency, saw-toothy signal, and get rid of the high frequency noise that is present. Is that right? – Jim Clay Oct 3 '14 at 19:47

If you know your carrier is always exactly 16kHz (within a few percent or so), and you have sampled the audio at 48kHz, you can try a simple 3-tap FIR filter approach:

$$Smoothed(k) = \frac{1}{3}( Sig(k) + Sig(k-1) + Sig(k-2) )$$

This assumes your original signal is called $Sig()$, and it computes a new signal, $Smoothed()$.

The method exploits the fact that three sample periods equates to one entire cycle of a 16kHz sine wave, so an 16kHz component in the input signal will be cancelled (since summing all the samples of a full sine wave cycle will result in zero).

The resulting $Smoothed()$ signal should look like you original plots, with the furry 16kHz components gone.

If your sample rate is not 48kHz (let's call it $F_s$), or if your interfering sine wave is at some other frequency (let's call it $F_i$), you can craft the 3-tap filter as follows:

$$Smoothed(k) = \frac{1}{2-2\cos(\omega)}( Sig(k) - 2\cos(\omega) Sig(k-1) + Sig(k-2) )$$

where $\omega = 2\pi\frac{F_i}{F_s}$ (note that, if $F_i=16000$ and $F_s=48000$, we get $\omega=\frac{2\pi}{3}$ and hence $\cos(\omega)=-\frac{1}{2}$. If you substitute this into the second equation, you will simply get the first equation again.

This method is simply creating a $2^{nd}$ order FIR filter with zeros at $\pm F_i$, and with the gain at DC normalised to unity.

Similar to dave_mc's answer, the basic approach to do is to run the data through a low-pass filter that will eliminate the 16 kHz noise. The passband edge would be the highest frequency of your signal of interest- 4 kHz in this case. The stopband edge would be the lowest frequency of your noise.

If dave_mc's targeted FIR approach works, then great. If you want a more generalized low-pass filter that is computationally efficient than I would probably use an IIR filter.

Once the noise is removed I would search for local peaks and use them to determine where the cycles are repeating. You should then be able to determine the cycle frequency.

• Yes, Jim is providing the more comprehensive answer. The answer I provided simply ensured that the interfering 16kHz tone was suppressed, but it didn't take care to ensure the low frequency region was 'flat' in response. A longer FIR, or an IIR, would be needed if you want to be more careful to preserve the low frequencies more accurately. – dave_mc Oct 4 '14 at 21:46