Sunday, November 1, 2015

Adding FM to the mcHF SDR transceiver

This has been one of those "Rabbit Hole" features.

In the past I have stated several times on the Yahoo Group that I would not be adding FM to the mcHF (a completely stand-alone QRP SDR HF transceiver) any time soon, mostly because I was quite certain that there was simply not enough processor horsepower to do it properly, but quite recently I (sort of) got obsessed with making it work, going from "0 to 60" in just a few evenings of code "hacking".

While it took only an hour or so to get the FM demodulation and modulation working it ultimately took much longer than that to integrate the other features (subaudible tone encode/decode, etc.) and especially the GUI interface with everything!  By the time I was done I'd spent more time than I had hoped (not unexpected!) but at least had something to show for it!

FM on an HF transceiver:

First of all, FM is one of those modes that I have used on HF only a few dozen times in my 30+ years of being a ham - using it most often (albeit rarely) when 10 meters is open and I hear a repeater booming in, but other than that I haven't really had any reason to do so, particularly since there are no local 10 meter repeaters and local activity on "10 FM" is quite sparse.

Figure 1:
Reception of an FM signal as displayed on the waterfall (using the
"blue" palette) showing the sidebands from the 1 kHz tone
modulated onto the carrier being received.  The white background
on the "FM" indicator shows that the (noise) squelch is open.
Click on the image for a larger version.
What might be a practical reason to add FM to the mcHF other than for 10 meter openings or with a transverter (or a modified radio) on a higher band such as 6, 4 or 2 meters where FM is common?  I asked this question on the mcHF Yahoo group and several people noted that in various parts of Europe, FM repeaters and simplex operation on 10 meters is/are (apparently) more common than here in the U.S - not to mention the fact that I suspect that some mcHF users like to hang out on "CB" frequencies where FM is used in Europe.


As it turns out I was recently adding/fixing some of the current mcHF features, streamlining some code and I decided to look into what, exactly, it would take to demodulate FM.

Before I begin the description it should be noted that the mcHF, in FM receive mode, must utilize "frequency translation" which shifts the local oscillator by 6 kHz - this, to get away from the "0 Hz hole" intrinsic to many SDR implementations that down-convert the RF to baseband:  If we did not do this the FM carrier would land in this "hole" and hopelessly distort it!

With the signal to be received centered at 6 kHz at the input of the A/D converter, a software frequency conversion shifts it back to "0 Hz" where, in the digital domain, the hole does not exist.  True, the FM signal is now modulated +/- zero and includes "negative" frequencies, but since the signals are quadrature and it is just math at this point we can get away with it!

(Note:  The "0 Hz hole" still exists but is now 6 kHz removed from the center of the carrier so it has no effect at all on demodulated signals in receive bandwidths up to 12 kHz.)

The PLL method of demodulating FM:

The most common way to do this is via a PLL, implemented in software
Figure 2:  PLL implementation of an FM demodulator

Depicted in Figure 2 this works by "tracking" the variations of the input signal's frequency using the PLL:  Differences in instantaneous phase are detected, applied to the VCO's tuning line via the Loop Filter.  The loop filter is present to remove the energy from the original carrier frequency, effectively leaving only the audio modulation behind, a sample of which is high-pass filtered to remove the DC content and used to extract the demodulated audio.

In hardware this type of scheme is used in PLL ICs such as the NE564 and NE565, or even the good old 4046 PLL IC:  Many implementations of hardware-based FM demodulators may be found on the internet using these chips!  (Hint:  Google "NE565 SCA decoder").

In software this method would typically be applied in those instances where the "carrier" frequency was high, compared to the highest modulated frequency contained in the FM signal to be demodulated and the "VCO" would be an NCO (Numerically Controlled Oscillator) - essentially a software-based DDS (Direct Digital Synthesis) "oscillator."  In a typical SDR application the implementation would appear more complex than in the above block diagram, using both the I and Q channels as part of the phase detector (and to avoid ambiguity since both are needed to avoid the "frequency image" anyway) - but the intent is quite clear.

Out of curiosity I decided to implement this on the mcHF, but as expected it was to "expensive" in terms of processing power - plus, the "carrier" frequency (in software) was only 6 kHz - not too far above the highest modulated frequency.  I could hear the audio, but it was somewhat distorted.

The "arctangent" method of demodulating FM:

Applying another tactic I went for the "arctangent" method.  If you recall your trigonometry, the arctangent is that number that you get when you input the ratio between the two sides of a triangle to yield the angle.  Related to the arctangent is the "atan2" function that appeared in computer languages where not just the ratio is inputted to the function, but the actual lengths of the sides of the triangle (y, x) and the angle is computed from that.

If we consider the instantaneous amplitudes of our I and Q signals to be vectors, we can see how we can use this function to determine the angle between those two vectors at any given instant - and since FM consists of rapidly changing phases (angles) we can therefore derive about the frequency modulation:  The more the angle changes, the more deviation!  (More or less...)

Figure 3:  Speech-modulated audio being received and displayed
on the "Spectrum Scope" showing the width of a typical
voice-modulated, pre-emphasized FM signal.  The red "FM"
indicator shows that the subaudible tone is being received and
properly decoded.
Click on the image for a larger version.

In order to do this you must know how the vector has changed from one sample to the next, using previous information to do so, so a bit of math is first used to accomplish this as described in the following code snippet:

   y = Q * I_old - I * Q_old
   x = I * I_old + Q * Q_old
   audio = atan2(y, x)
   I_old = I
   Q_old = Q

   "I" and "Q" are our quadrature input signals
   "audio" is the demodulated output, prior to de-emphasis (see below.)

Because we supply it with both x and y, "atan2" function has the convenient feature of knowing, without ambiguity, the quadrant from which the two sides of the triangle are derived - something not possible from the normal "atan" function.  For example if our vector is +1, +1 - a ratio of 1 - we know that our angle is 45 degrees in the first quadrant, but if our vector is -1, -1 - our ratio is still 1, but clearly this angle is in the fourth quadrant and the normal "atan" function would give us a completely bogus answer - but "atan2" would faithfully yield the correct answer of 315 (-45, actually) degrees.

If you are coming from the analog world you know that one of the necessary steps in properly demodulating an FM signal is to apply limiting after bandpass filtering, but before the actual FM demodulation - this being a process where incoming signal is typically amplified and then strongly clipped - often several times - to assure that the amplitude of the resulting signal is constant regardless of the strength of the original signal.  The reason for this is that most analog FM schemes are either amplitude sensitive to a degree (e.g. slope detection, the "Foster-Seeley" discriminator - link, or even the so-called "ratio detector" - link) or can operate over only a somewhat limited amplitude range and still maintain "linearity" in their frequency-dependent demodulation.

As it turns out the while both of the aforementioned schemes are amplitude-insensitive with this limiting applied, the "atan2" method can be considered to be the ultimate "ratio detector" in that all it really cares about is the ratio of the vectors from the I and Q channels and not a whit about their amplitudes!  If the signal is reasonably strong, both channels (I and Q) will reflect the instantaneous angle-change of the received signal with respect to the previous sample.  As with any other method of detection of frequency modulation as signals get weaker, noise begins to intrude, causing uncertainty and the calculation of the instantaneous angle begins to be contaminated with random bursts of energy which naturally shows up as "popcorn" and/or "hiss" in the recovered audio.

Rather than using the compiler's rather slow, built-in floating-point "atan2()" function I decided to use the "Fixed point Atan2 with Self-Normalization" function (in the public domain) attributed to Jim Shima posted (among other places) on the DSP Guru Site (link here).  Actually, this algorithm was quite familiar to me as I'd unwittingly derived a very similar method many years ago on a PIC-based project in which I needed to do an ATAN2-like function using integer math to derive the bearing on a direction-finding (DF) system. (The DF system is decribed here - link)

Needless to say, this algorithm is blazing fast compared to the built-in, floating-point "atan2" function and demodulating FM with this much horsepower simply would not be possible without its "cost savings" and the accuracy of the result easily yields sub 1% THD (distortion) - more than adequate for communications-grade FM.

De-emphasizing the demodulated audio:

The audio that spits out of the "atan2" function is proportional to the magnitude of the frequency deviation at any modulated frequency (within reason, of course!) - but in amateur radio, at least for voice communications, we do not use "FM" per se, but rather "Phase" modulation (PM).  Without going into the math, the only thing that you need to know is that in order to use an FM modulator to generate a PM-compatible signal one must "pre-emphasize" the frequency response of the audio at a rate of 6 dB/octave.  In other words, if you were set a signal generator to produce +/- 2 kHz of deviation with an audio signal of 1 kHz, if you change that audio signal to 2 kHz - but kept the audio level the same - the deviation would increase to +/- 4 kHz of deviation when you are using PM.

If you did not do this pre-emphasis, your audio would sound muffled on an ordinary amateur "FM" receiver.  Conversely, if you use an "FM" receiver for the reception of PM you must apply a 6 dB/octave de-emphasis to it:  Without this the audio tends to sound a bit "sharp" and tinny.

There is a practical reason for doing this and it is in the form of "triangle noise" - that is, as an FM signal gets weaker, the recovered audio does not get quieter, but it gets noisier, instead, with the noise appearing in the high frequencies first as high-pitched hiss.  By using "PM" (or more typically, "true" FM with pre-emphasis on transmit and de-emphasis on receive) we reduce the intensity of this high-pitched noise on weaker signals:  Since we are boosting the "highs" on transmit and then reducing them back to normal on receive, those audio frequencies that would be first affected by noise as the signal weakens are maintained at higher levels while at the same time reducing the amplitude of the high frequencies in which the noise will first appear, preventing the phenomenon by which the high frequency component would otherwise be the first to disappear into the noise with weak signal.  The end result is that with PM, the signal can be weaker - and seem to be noise free - more than is possible with "straight FM".

For an explanation of noise in FM signals, in general, read the page "Pre-Emphasis (FM) Explained" - link.

In an analog circuit this de-emphasis is as simple as an "R/C" (resistor-capacitor) low-pass filter (series resistor followed by a capacitor to ground) and it may be simulated in code as follows:

  filtered = old + α * (input + old)
  old = input

   "α" is the "smoothing" parameter
  "input" is the new audio sample
  "output" is the low-pass (integrated) audio data

In the above, the output data is proportional to the previous output and the next input which means that as the rate-of-change increases, the output decreases - effectively forming a single-pole low-pass filter of 6 dB/octave.

If you were to implement this with real components (resistor, capacitor) you would not select them for really low frequency as this would mean that by the time you got to speech frequencies (1-2 kHz) your audio would rolled of by many dB - but this would also mean that low-frequency components (subaudible tones, AC hum, even the low-frequency components of noise) would seem to be artificially amplified and could "blast" the speaker/amplifier.  Instead, one would select a "knee" frequency above which one would start to roll off the audio - typically just below the bottom end of the "speech" range of 300 Hz or so and by doing this the low frequencies are not as (seemingly) amplified as they would by otherwise.  As it turns out, with an "α" setting of 0.05 or so we can achieve a reasonable (low frequency) "knee" frequency at a sample rate of 48 kHz.

Even if we appropriately select a "knee" frequency as above our audio amplifier/speaker will still get blasted by low-frequency noise since we must still amplify the signal by well over 10 dB to get reasonable amplitudes at speech frequencies, but we can - with a "differentiator" - the inverse of (but similar to) the integrator described above, knock off these low-end components.  In software this differentiator function (which, in the analog world, is a series capacitor followed by a resistor to ground) is performed as demonstrated below:

  filtered = α * (old_input + input - old_filtered)
  old_filtered = filtered
  old_input = input

  "α" is the the equivalent of the time constant in that a "small" α implies an R/C circuit with a fast time-constant strongly affecting "low" frequencies.
  "input" is the new audio sample.
  "filtered" is the high-pass filtered (differentiated) audio

Setting "α" to 0.96 (with a sample rate of 48kHz) put the "knee" roughly in the area of 300-ish Hz and with the "low-pass" (integrator) and "high-pass" (differentiator) cascaded the low-frequency speech components were minimally affected, but the combination of the "knee" frequency of the integrator and the nature of the differentiator meant that the very low components (below approximately 200 Hz) were being attenuated at a rate of around 12dB/octave - all by using simple filtering algorithms that take little processing power!  Again, it is important that we do this or else the very low frequencies (subaudible tones, the "rumble" of open-squelch noise) would be of very high amplitude and easily saturate both the audio amplifier and speaker, causing clipping/distortion at even low audio levels.

At some point I may attempt to design an FIR or IIR filter that will both de-emphasize the audio at 6dB/octave and filter out the low frequencies used by subaudible tones but I wanted to at least try the above method which was pretty quick, easy to do, and had a fairly low processor burden.


One factor not mentioned up to this point, but extremely important - especially with FM - is that one must bandwidth-limit the I and Q channels before demodulation.  More than in the case of AM, off-frequency signals will contribute to noise and nonlinearity in the demodulation process and it is easy to see why:  If we are simply using vectors with our "atan2" function to recover the frequency modulator, anything that contaminated that information would distort and/or add noise to the resulting audio so it is important that we feed only enough bandwidth to the demodulator to pass "enough" of the signal.

Defining the bandwidth of a modulated FM signal is rather tricky because it is, in theory, infinitely wide. In practice, the energy drops off rather quickly so the "far out" sidebands soon disappear into the noise, but how quickly can we "clip off" the "close in" sidebands?  Clearly, we must have at least enough bandwidth to pass all of our audio, and since the FM signal is symmetrical about its center, it's twice as wide as that.  There is also the issue of the amount of frequency deviation that is used.  If we take our example of +/- 2.5 kHz deviation in "narrow" mode we know that just because of that, alone, our signal must be at least 5 kHz wide!  It would make sense, therefore, that the actual bandwidth of the signal is related to both the amount of deviation and the audio imposed on it - and it does, and this is called "Carson's Rule" and you can read about it here - link.  This rule is:

 occupied bandwidth = 2 * (highest audio frequency) + 2 * (deviation)

If we have +/-2.5 kHz deviation and our audio is limited to 2.6 kHz the calculated bandwidth would be 10.2 kHz.  It should be remembered that this is considered to be the occupied bandwidth of the signal and generally indicates the minimum spacing between similar signal, but it turns out that if we are willing to put up with minor amounts of signal degradation our receive bandwidth may be narrower.  By cutting off a few extra sidebands the result is a bit of added distortion since part of signal that represents the vectors presented to the "atan2" function have been removed and the representation is understandably less-precise.

In the case of the mcHF, filtering for the FM demodulator is done by the same Hilbert transformers that are already present for "wide" SSB and AM demodulation where they can also be configured to provide a low-pass function.  For example, there exist 3.6, 5 and 6 kHz low-pass versions of the Hilbert transformers that provide the 90 degree I/Q phase shift and coupled with the fact that these would operate both above and below center frequency, they yield approximate detection bandwidths of 7.2, 10 and 12 kHz, respectively.  Using a filter wider than 12 kHz (+/- 6 kHz) is problematic in this implementation because, as noted earlier, we are shifting our signal by 6 kHz and with a 12 kHz bandwidth, one edge of the filter actually falls in the "zero Hz hole" of the hardware.  This is not a problem at the 12 kHz bandwidth, but it is a problem at wider bandwidths and can result in significant distortion.

While receive bandwidths more than 12 kHz could be obtained using a shift greater than 6 kHz, testing (both on-the-bench and on-air) has shown that "wide" +/- 5 kHz deviation signals may be received with no obvious distortion with the 12 kHz bandwidth setting - and even the 10 kHz setting is very "listenable".

Surprisingly, if you cram a +/- 5 kHz deviation signal through the 7.2 kHz filter, the results are generally quite usable although distortion and frequency restriction are becoming evident and there may be the risk of clamping if the squelch is set too tight.  One advantage of a 7.2 kHz filter over a 12 kHz filter is that the former, being only 60% as wide, will intercept commensurately less noise on a weaker signal which means that it may be possible to gain an extra dB or two of receiver sensitivity by switching to the narrower bandwidth - if one is willing to accept the trade-off of lower fidelity!

In a later posting I'll talk about the squelch "circuit", subaudible tone detection as well as frequency modulation.


This page stolen from "".


  1. Not only is this a super achievement, your willingness to share in the creative journey is also most appreciated. The Yahoo group, by necessity, seems to drive more concise (and sometimes difficult to follow) email chains that jump off at a tangent in mere seconds of a thread starting. Knowing you'll post to your blog a more detailed and insightful description is just such a bonus.....and I don't have to read endless complaints about why you aren't using git :)

    I just pray you have the time & energy to keep rolling out such updates for the lovely mcHF, and help out those of us who are less technically capable :)

    Thank you for all your efforts; they really are very much appreciated


  2. Hi Clint,

    it is always a pleasure to read your concise and detailed explanation of how the different software parts for the mcHF work! I hope many of the mcHF users are aware of this site and work through all this material in order to understand how and why their ham transceiver works ;-).

    Thanks a lot for your great explanations. They are one major source of motivation and information for me not only as a user of the mcHF, but also for my other project, an SDR receiver based on the Teensy 3.1 microcontroller.

    Keep on the good work and thanks a lot!

    73 de Frank DD4WH

  3. can you share which programme you use it to analyze ???

    1. I used a service monitor (a.k.a. communications test set) to generate the test signals and the resulting demodulation, being able to directly measure parameters like distortion, bandwidth, sensitivity, etc.



While I DO appreciate comments, those comments that are just vehicles to other web sites without substantial content in their own right WILL NOT be posted!

If you include a link in your comment that simply points to advertisements or a commercial web page, it WILL be rejected as SPAM!