<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi All,<br>
    <br>
    This email is about a software/DSP enhancement that those of you
    writing software for the HPSDR (or other hardware) may want to
    consider.<br>
    <br>
    The explosion in popularity of the WSJT modes since the first of the
    year has presented me (and probably many of you as well) with a new
    problem, due to the now frequent occurrence of very strong local
    stations on the VHF digital frequencies where I am trying to work
    very weak, distant stations.  This was not previously an issue for
    me, as there were not other locals active on these frequencies.  But
    these frequencies are now like Grand Central Station in NYC.  <br>
    <br>
    I do NOT get RF overload from these strong local stations, that is
    well taken care of due to appropriate station design.  But the
    computer final audio stages cannot tolerate the wide range of signal
    levels present without some sort of AGC. <br>
    <br>
    And as everyone on this list knows, one does NOT want to run AGC for
    weak signal work digital or otherwise, because the action of the AGC
    on a strong station within the AGC passband will mask the weak
    stations.<br>
    <br>
    This problem was particularly vexsome on Monday of this week when a
    very strong local station seemed to be omnipresent.  I had 2 states
    of operation [1] AGC off and [2] AGC on.  With [1], the strong
    station would overload the audio when the audio levels were adjusted
    for proper copy of the weak DX stations.  With [2], when the strong
    station came on the weak stations' signal levels were pushed way
    down so that they were no longer copiable/visible.<br>
    <br>
    The problem with the usual AGC is that it is done in the time
    domain, and it is not frequency specific.  And to solve this
    interference problem we need frequency-specific AGC.<br>
    <br>
    But in the SDR receive chain we are in the frequency domain for
    audio filtering anyway, and so there is little computing penalty for
    adding some simple code that applies frequency-specific AGC to each
    individual FFT bin.<br>
    <br>
    It was a simple matter to write a few lines of code to add the
    frequency-specific AGC code to run immediately after the filter
    code, and the results thus far have been outstanding here with both
    JT65 and FT8 weak signal work in the presence of strong stations. It
    is only Thursday and I started playing with this only Tuesday, so
    more real world testing is to be done.<br>
    <br>
    But the results of this have been so outstanding for me that I
    wanted to share them with the rest of the group so that they can add
    this function to their software too.  My code is idiosyncratic to my
    software here, but the basic principles are general.  Here, the
    frequency-specific AGC code working in the frequency domain by
    limiting the signal strengths individually for each FFT bin is
    placed just after the filter deconvolution is done, and before the
    "usual" time-domain AGC, which I have disabled.  <br>
    <br>
    The approach I am using is to allow the user (me) to select a "knee"
    amplitude and a "limit" amplitude.  Signals below the knee amplitude
    are  passed without change. Signals above the knee amplitude are
    modified using these equations:<br>
    <br>
    ++++++++++++++++<br>
     thisMagnitude[i] = (float)Math.Sqrt(w3sz_tmp_cpx[i].real *
    w3sz_tmp_cpx[i].real + w3sz_tmp_cpx[i].imaginary *
    w3sz_tmp_cpx[i].imaginary)<br>
    --------------------------<br>
       float w =( -(float)Math.Log(1 - (1 / this.fagclimit))) /
    this.fagcknee;   <br>
                <br>
                for (int i = 0; i < size; i++)<br>
                {<br>
                    if (this.fagctype == "OFF")  //turns of time-domain
    AGC<br>
                    {<br>
                        if (thisMagnitude[i] > this.fagcknee)  //
    frequency domain formula for amplitude > knee amplitude<br>
                        {<br>
                            d.tmp_cpx_2[i].real = 0.0001f *
    this.fagclimit * (1.0f - (float)Math.Exp(-w * thisMagnitude[i])) *
    w3sz_tmp_cpx[i].real;<br>
                            d.tmp_cpx_2[i].imaginary =
    (d.tmp_cpx_2[i].real / w3sz_tmp_cpx[i].real) *
    w3sz_tmp_cpx[i].imaginary;<br>
                        }<br>
                        else  // frequency domain formula for amplitude
    <= knee amplitude<br>
                        {<br>
                            d.tmp_cpx_2[i].real = 0.0001f *
    w3sz_tmp_cpx[i].real;<br>
                            d.tmp_cpx_2[i].imaginary = 0.0001f *
    w3sz_tmp_cpx[i].imaginary;<br>
                        }<br>
                    }<br>
                    else  //if time domain AGC is to be used instead
    (separate code block), there is some level setting done here<br>
                    {<br>
                        d.tmp_cpx_2[i].real = 0.01f *
    w3sz_tmp_cpx[i].real;<br>
                        d.tmp_cpx_2[i].imaginary = 0.01f *
    w3sz_tmp_cpx[i].imaginary;<br>
                    }<br>
                }<br>
    +++++++++++++++<br>
    where:<br>
    w3sz_tmp_cpx is input<br>
    d.tmp.cpx_2 is output<br>
    <br>
    w sets the level of the signal at the knee calculated by the the
    formulas above to be  equal to the input signal, so that there is no
    discontinuity at the knee. <br>
    this.fagclimit is the limit amplitude<br>
    this.fagcknee is the knee amplitude<br>
    <br>
    The most useful range for user selectable signal limits here thus
    far is 1-20 and useful range for knees is 0.0001 to 0.02.<br>
    <br>
    the initial factors of 0.0001 and 0.01 in the above formulas are
    just to set baseline signal level as appropriate for my setup here.<br>
    <br>
    This approach should be easy for anyone to adapt to their software,
    and I've been very pleased with the results here.<br>
    And of course NONE of this would have happened without the work of
    Phil VK6PH  and Kiss Konsole.<br>
    <br>
    If you want more details on my software or want to download my
    entire codebase, you can go to <br>
<a class="moz-txt-link-freetext" href="http://www.nitehawk.com/w3sz/CSharpsdrclientANDserverVersion2pt0.html">http://www.nitehawk.com/w3sz/CSharpsdrclientANDserverVersion2pt0.html</a><br>
    <br>
    73,<br>
    <br>
    Roger Rehr<br>
    W3SZ<br>
    <br>
  </body>
</html>