Saturday 4 March 2017

frequency - Bandpass filter to isolate musical note "A2"


I would like to design a bandpass filter to isolate the musical note A2 ( 110Hz ) from its neighboring notes at a precision of a half-step. This means that G2# = 103.83Hz and A2# = 116.54Hz should be in the stop band.


In the ideal case, 110Hz would be at 0 gain. G2# and A2# would be silent (infinite negative gain?), and there would be a smooth roll-off from the A2 to each neighboring note.


How can I select my window type, determine how many coefficients are necessary, and calculate those coefficients?


I took a few EE courses back in college, but I am far from an electrical engineer, so please ask for clarification where it is necessary.


References:




Answer




As I understand it, you want to detect the amplitude of 110 Hz component with a bandwidth of less than the 12th root of 2 on either side. The adjacent notes that should not be detected are 103.8 Hz and 116.5 Hz, which are about 6% off from the center frequency.


First, that is a very tight filter. This is not going to happen with analog electronics, at least not in the baseband.


You can do this digitally by sampling the composite input signal and multiplying it by the sin and cos of 110 Hz. Low pass filter each of these products so that 6 Hz is attenuated to the level you want adjacent notes attenuated. Then square each of the results and sum them. That single number will be the square of the recent amplitude of any 110 Hz component in the input signal. Keep in mind that since this filter has very narrow bandwidth, it will respond slowly. It will take a few 100 ms to stabalize from a step in the incoming 110 Hz amplitude.


If you just want to detect that the 100 Hz component is above some threshold, then you can use the squared amplitude value directly. If you need the real amplitude, then you'll have to take the square root of the result.


I have done something similar to detect individual DTMF frequencies in a DTMF signal. The frequencies, bandwidth, and therefore the time constants are different, but the algorithm is identical. Here is a result showing the amplitude squared value I described above for three successive DTMF frequencies with the algorithm set up to detect the middle one:



Here is the code snippet that ran over each input sample to produce the squared magnitude (MAGSQ) and the real magnitude (MAG):



for sampn := 0 to nsamp do begin {once for each input sample}
t := sampn * sampdt; {make time of this sample}

samp := getsamp (t); {get input sample}
r := t * freq; {make reference frequency phase}
ii := trunc(r);
r := r - ii;
r := r * pi2;
prods := samp * sin(r); {mix by ref frequency sine and cosine}
prodc := samp * cos(r);
filter (filts, prods); {low pass filter mixer results}
filter (filtc, prodc);
magsq := sqr(filts.val) + sqr(filtc.val); {compute square of magnitude}

magsq := magsq * 4.0; {normalize so input 1.0 results in 1.0}
mag := sqrt(magsq); {compute linear magnitude}

The FILTER subroutine performs a two pole low pass filter the usual way. Each pole follows the standard algorithm:


FILT <-- FILT + FF(NEW - FILT)


In this case FF is 1/128. Since it is a integer power of two (-7 in this case), it could be performed in a microcontroller by a right shift of 7 bits.


No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...