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.