Then I worked my way through the code. I think I understand what you are doing now.
Using my neophyte C coding knowledge, here is what I think you are doing:
You buffer the I and Q signals from the codec at whatever the sample rate is
You decimate them by 4 and then 2 (for a total of 8)
In the Digital Convolution section of the code:
you do all the buffer management stuff
you don't have the Nuttall window working so you don't window the buffer
you perform a complex FFT
there is an autotune thing I haven't figured out
you zero either the I or Q buffer to get LSB or USB (I didn't know that worked) or you do nothing for the other demodulators
you apply the complex filter with a 512 coeff FIR complex filter kernel
you apply a notch if it is enabled
you perform the ifft
It looks like the filter kernel is created in "calc_cplx_FIR_coeffs" and is a low pass windowed sinc filter using a Blackman-Nuttall window but you slide it up for a bandpass filter. Is that right? That is a neat trick for making a variable band pass filter.
Bill, exactly, you got it, excellent!
Some further comments on the signal flow:
* I & Q samples coming in with user-defined sample rate (as an example, lets take 96ksps)
* spectrum display (256-point FFT) can display a maximum bandwidth of 96kHz and runs at the original sample rate
* I & Q phase and amplitude are being automatically corrected by the algorithm of Moseley & Slump (so there is no need to tweak I & Q in hardware!)
* S-meter / signal level is calculated from the results of the spectrum display FFT bin magnitudes
* frequency translation by sample rate / 4, thus the IF is at 24kHz
* the desired signal is now at baseband, but still @96ksps
* decimation-by-8 in two steps (to lower the needs for steep anti-alias lowpass filters)
* now I & Q are in 12ksps sample rate [and thus the audio bandwidth is restricted to some figure lower than 6kHz]
* 512-point-FFT works in 12ksps sample rate
* the complex-multiply uses complex FIR filter coefficients [you are right, the function calc_cplx_FIR_coeffs calculates a lowpass and shifts this until we have the desired BANDPASS, IIRC, the window used is a Blackman-Harris 4-term window with a maximum sidelobe suppression of > 100dB]
* and now comes the magic: because we calculate a COMPLEX bandpass, the coefficients already contain the Hilbert transform to suppress the opposite sideband! So there is NO need to delete bins or add/subtract in order to obtain LSB or USB. Just define the bandpass, so that it cuts out the desired sideband and you are done and the opposite sideband is already suppressed (because we corrected I & Q, sideband suppression can reach 60-65dB!)
* frequency domain manual notch filter [very quick and dirty: cuts out bins]
* 512-point inverse FFT in 12ksps sample rate
* AGC (in the low sample rate to save processor cycles)
* digital mode decoders (EFR, RTTY)
* DEMODULATION: do nothing for SSB
* DEMODULATION: calculate magnitude from I & Q for AM
* DEMODULATION: calculate atan2 (Q,I) for narrowband FM [not yet implemented !]
* DEMODULATION: synchronous AM contains another Hilbert transform and a PLL
* auto-notch LMS-algorithm
* LMS noise reduction
* frequency domain noise reduction for weak signals [two different algorithms]
* CW decoding/RTTY decoding
* interpolation-by-8 in two steps (for the same reason stated above)
Thats it . . .