Geortzel DFT implementation checked in

Checked in to CVS are a C++ implementation and stream processing block
for the Goertzel single-bin DFT transform.

The C++ class constructor takes the sample rate, length of the Goertzel
block, and the frequency of the bin of interest:

gri_goertzel::gri_goertzel(int rate, int points, float freq);

The frequency does not have to be “centered on a bin” such as when doing
a standard DFT.

By calling the dft member function with a pointer to an array of floats,
one receives the real and imaginary parts of the DFT transform of the
array for the frequency specified in the constructor:

gr_complex gri_goertzel::dft(float *input);

Wrapped around this is a signal processing block that accepts a
real-valued stream of floats and outputs a complex stream of DFT
outputs, at a rate equal to the input rate / length of the Goertzel
transform:

gr.goertzel_fc(rate, points, freq)

Basic testing with a variety of inputs shows correct functioning but no
automated QA script is in place yet.

The C++ class will be used as part of the planned gr.ctcss_squelch()
block.

-Johnathan, AE6HO

Thanks for the new function.

I am also interested in a CTCSS function.

Couldn’t we take the output of your new goertzel_dft function, pick out
the
particular frequency bin we are interested in by using stream_to_streams
and
then pass that to the existing power_squelch function?

If this makes sense, I am having trouble converting the output of the
goertzel_dft function into separate frequency bin streams.

Any suggestions would be appreciated.

Regards,

Tom Rychener

Tom Rychener wrote:

I am also interested in a CTCSS function.

I have a gr.ctcss_squelch_ff block as work in progress (see below.)

Couldn’t we take the output of your new goertzel_dft function, pick out the
particular frequency bin we are interested in by using stream_to_streams and
then pass that to the existing power_squelch function?

If this makes sense, I am having trouble converting the output of the
goertzel_dft function into separate frequency bin streams.

The Goertzel algorithm is a computationally efficient way to compute a
single DFT bin. It is more efficient to use than an N-point FFT if all
you need is less than log2(N) individual bins.

The gr.goertzel_fc constructor takes three arguments–the input sample
rate, the Goertzel transform length (“points”), and the frequency of the
bin of interest. It accepts a stream of floats on its input, and for
every “point” inputs, outputs a single complex DFT output corresponding
to the frequency chosen during construction. The Goertzel block length
determines the selectivity of the transform (longer is better), but also
sets the amount of time needed to detect a tone.

So an input stream at 8000 sps with a 1000 sample Goertzel length will
output 8 DFT values per second, of the same frequency bin, as a stream
of complex values. This output stream may be used in a variety of ways
in a flow graph, but not directly as a way of controlling a mute
function in a separate block.

The gr.goertzel_fc block itself depends on another internal C++ class,
gri_goertzel, to do the actual calculation of the output based on an
array of floats on the input.

Unfortunately, a CTCSS squelch block needs to “internally” calculate the
power of the squelch tone and use it to decide whether to pass, gate, or
zero the signal from input to output. The block I am writing uses the
same internal gri_goertzel class to do so. In fact, because of the tight
constraints on CTCSS tone discrimination, the block uses three
Goertzels, one at the desired frequency and one at each adjacent CTCSS
tone. The squelch only gets unmuted when the desired tone is stronger
than the other two and is also at least 10% maximum deviation. This lets
the Goertzel block be much shorter, and allows CTCSS tone detection in
about 100-125 ms.

I’ve got it working in pure Python with some artificially generated
input signals + noise. It’s rough and I’m not sure it has all the right
trade offs in selectivity, detection time, and noise immunity.

I expect to have the gr block completed this next weekend, and once it
passes muster with off-the-air signals I’ll check it in.

-Johnathan, AE6HO

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs