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