3
$\begingroup$

I've been googling for a while and came across the audio cookbook and Bjorn's blog explaining it further Link Here.

Background info: I've modified the rtl-sdr open source code to tune to a VOR station (transmits heading, typically used for aircraft). I tune to 113.1 MHz which is the the frequency the nearby VOR station transmist data. Inside that 113.1 MHz frequency, there are 3 signals;

  1. Morse Code at 1020Hz
  2. Reference Signal (9960Hz +- 480Hz) (FM this signal, inside this there is another 30Hz signal)
  3. Variable Signal (30Hz)

I'm trying to isolate these signals. Now when I tune to the station (113.1MHz) and perform amplitude modulation, I can hear the Morse code signal from the speaker with lots of noise in the background. I followed the audio cookbook guide along with Bjorn's implementation to write a BPF function (pasted below) to isolate the Morse code signal (1020Hz) to hear only the morse code with very little to no noise in the background. However, I just about hear nothing, it's like someone just really lowered the volume almost to mute. I'm starting with this because if I can actually hear the morse code signal, then that proves that the BPF works and now I can use that function to isolate the other two signals.

The values I used to compute a0 to b2: I also did normalize the a0 to b2 values.

  1. Sample Rate: 24KHz
  2. Center Freq: 1020Hz
  3. BW (in octaves): 1 (don't really understand this)
  4. gain: 1 (assuming 1 should be ok but again not really sure)

BPF Function in C Language:

int band_pass_fir(struct morse *_m, int16_t *_signal, int _len)
{
  // _m->signal (int16 array) is my desired output
  // _signal (int16 array) contains the actual amplitude modulated data received from the signal
  // _len is the length of _signal

  int i = 2;

  const float b0 = 0.1205498139,
              b1 = 0,
              b2 = -0.1205498139,
              a1 = -1.7626236142,
              a2 = 0.8273910712;

  while (i < _len)
  {
    _m->signal[i] = (int16_t)(b0 * _signal[i]) +
                    (int16_t)(b1 * _signal[i-1]) +
                    (int16_t)(b2 * _signal[i-2]) -
                    (int16_t)(a1 * _m->signal[i-1]) -
                    (int16_t)(a2 * _m->signal[i-2]);

    _m->signal[i-2] = _m->signal[i-1];
    _m->signal[i-1] = _m->signal[i];

    i++;
  }
}

Questions:

  1. To isolate this 1020Hz signal, is it safe to assume I need a BPF? or do I need some other type of filter?
  2. Assuming whatever type of filter I need to isolate the 1020Hz would be the same type of filter I would need to isolate the 30Hz signal (variable signal) ? Is that correct?
  3. Do you see if I'm doing anything wrong with my above method?
$\endgroup$

2 Answers 2

2
$\begingroup$

There are a few potential issues:

  1. Your code doesn't compute a full output vector, you just keep the last three samples (often referred to as "state variables". Your output should be a vector of the same length as the input
  2. This is only a second order filter. Depending on the exact properties of your signal, this may not be enough to isolate the component that you want. I'd recommended a Butterworth bandpass filter. In this case you can independently control the lower cutoff and the higher cutoff of your bandpass and also the steepness of the slopes. There are butterworth design tools in "Octave", see http://octave.sourceforge.net/signal/function/butter.html
  3. If you need to go to higher order filters, they should be implemented as "cascaded biquads" or "cascaded second order sections". There are tons of code examples to be found through google
$\endgroup$
2
1
$\begingroup$

Just as a quick suggestion, try moving the two _m->signal[i-2] and _m->signal[i-1] assignments above the _m->signal[i] assignment. It's unlikely that you want _m->signal[i-1] to be equal to _m->signal[i] at the end of that routine.

$\endgroup$
1
  • $\begingroup$ Thanks for the suggestion but that doesn't help. If you look at the link, the site does it the same way. Since this is in a while loop, it doesn't really matter if _m->signal[i-1] = _m->signal[i] because on the next iteration, _m->signal[i-1] will be used to compute the next _m->signal[i]. This loop is really designed to process one index at a time and save it to the next element. $\endgroup$ Nov 14, 2013 at 6:44

Your Answer

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

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