

The Muslim Brotherhood can't even penetrate the Egyptian government.
Ibrahim ali Iraqi, on claims that Hillary Clinton aide Huma Abedin is a member of the Muslim Brotherhood.
Yes, I've covered frequency demodulators before (Post #1, Post #2, Post #3). The problem is that I tend to use those posts as references. The information I need is scattered amongst those three posts. Here, I'm going to consolidate the ones that are unique to each other. I'm also going to add some details that I didn't understand (or even know) at the time of the original posts.
There are five unique methods (so far!) for frequency demodulating a signal using digital techniques. These are:
Let's dig in.
Frequency is a change of phase over time. Put in mathematical terms, this is:
where:
There are two ways to calculate this phase difference. These are to calculate the phase, then calculate the difference. The second is to calculate the difference, then calculate the phase.
The first phase differential method is just calculate the phase of each sample, then subtract the phase between samples. Straightforward, right? Not so fast. There's the +/-π phase boundary problem. My original solution for that was not elegant. Like, at all. Until I read a post on the DSPrelated.com website that explained that there is a way to make it work. It involves the use of integers. In math using integers, typically, if there's overflow (the numbers go past their limits), the numbers will "wrap-around". This means that, if they go past their upper or lower limit, the numbers will go to the other extreme and continue.
For example, using a signed 16-bit integer ("short"), if the value is at the upper limit (+32767), and one more is added, it will flip around to the lower extreme (-32768).
Here's an example using Gnu Radio Companion (GRC). The flowgraph uses a basic sinusoid which is converted from floating point numbers ("floats") to "shorts" (signed 16-bit integers). Due to the scaling at the input of the "Float to Short" block, the sinusoid amplitude is at the limits of what the "short" data type can handle (+/-215). The output is split to show how the addition of values changes the waveform and shows the "wrap-around" affect.
We can use this same concept for a frequency demodulator. First, calculate the phase of each sample. Second, convert that phase from floating point to integer. Finally, calculate the difference using integer math (so that any values that cross the +/-π boundary wrap around). I'm going to call this (in honor of Mark Napier, the engineer who allowed me to understand it) the "arctan and derivative" method.
A quick aside. You cannot do with this the floating point numbers, then convert them to integers and expect the "wrapping" to work. In Gnu Radio, any numbers outside of the limits of the integers will not wrap, they will be clipped. Hence, to make this work, you must convert to integer values first, then perform the math that requires the wrapping to occur.
Guess what? It works. Below is a flowgraph using this concept.
Personally, I think this works really well. My only issue is the conversion to an integer, specifically a "short" (16-bit integer). The 32-bit floating point numbers that GRC normally uses for processing provides 23 bits of dynamic range. Thus, we're losing 7 bits of dynamic range converting to the short. What if we used the GRC "integer" data type (32-bit integer)? Well, in that case, we'd gain 9 bits. Unfortunately, I've not been able to figure out how to make that work in GRC. Yet. I'll keep trying.
The second method for calculating the phase difference is to first calculate the difference, then calculate the phase. This is the basis of the (improperly-named) Quadrature Demod block in Gnu Radio. You might be wondering, "How do you calculate the difference of the phase before you actually calculate the phase?" Excellent question! It's one of those things that you can do with complex numbers, as James Shima explained in his 1995 paper. Complex numbers can be represented in either Cartesian format (e.g. x+jy) or in polar format (e.g. Mejω). They are equivalent representations. The values relate as follows:
This leads to how we can calculate the difference before we calculate the actual phase. If you multiply two complex samples together using the polar notation, you get:
For our purposes, we don't care about the magnitudes. We only care about the phase. This reduces the equation to the following:
When you multiply two numbers of the same base, their exponents add. Thus, the equation becomes:
This would give us the phase sum. We want the phase difference. To do this, we need to flip the sign of the second value. Since these are complex samples, there's an easy way to do this. That is to flip the sign of the imaginary component. The term for this is the complex conjugate. If we conjugate the second value, we wind up with the following equation:
This leads to the general flow of calculating the phase difference before you actually calculate the phase is as follows:
Once you've completed these, three steps, you've calculated the phase difference even though you've not yet calculated the actual phase. The only thing left to do is to calculate the actual phase, which in GRC can be done using the "Complex to Arg" block (the "argument" in math terms is the same as the "arctangent").
At which point, the signal is frequency demodulated. We call this a polar discriminator because we're using the polar format of complex samples to effectively perform the demodulation. To be clear, we DO NOT have to change the complex samples to the polar format before we perform these calculations. We simply take two, consecutive samples, conjugate the previous one, and multiply them together. That's because the Cartesian forms and the polar forms are the same. Thus, looking at the flowgraph below implementing this concept, note that there are no "Cartesian to Polar" blocks. Just conjugate the delayed sample, multiply the two consecutive samples together, calculate the phase of the product sample and VIOLA! Instant frequency demodulation.
But, wait, you might ask. Why doesn't this method have to worry about the +/-π boundary problem? I had the same thought, but I figured out the reason why it works.
What this has done is to calculate the phase difference. But remember that frequency is a change of phase over time. Where's the time difference? Well, since this is a sampled signal, the time difference is the sample period (the time between samples). This leads to:
where:
Dividing by the sample period is the sample as multiplying by the sample rate. Which means the calculation can be:
where:
The one problem left is that the units for this calculation would be in radians. As an engineer, we're used to hertz (Hz). The conversion from radians to Hz is to divide by 2π. The calculation now becomes:
where:
The calculation above would provide a result in which the amplitude would be the actual frequency deviation of the original FM signal. For example, in the US, FM broadcast stations use a deviation of 75 kHz or higher (up to 82 kHz, in some cases). Even a relatively narrowband FM transmitter would still be several thousands of Hz. To account for this, the last part of our scaling will be to normalize the output amplitudes due to the deviation. This means to divide by the deviation value. The final equation becomes:
where:
This is where the "Gain" value that you find in the "Quadrature Demod" block comes from. To summarize, it breaks down as follows:
Putting this altogether into a flowgraph, we wind up with the following:
This frequency demodulation method is how GRC's "Quadrature Demod" block works. Thus, we could replace all of the blocks between the output of the lowpass filter and the input of the time and frequency sinks with the "Quadrature Demod" block, as shown below:
Note that the "Gain" value of the "Quadrature Demod" block is the scaling value we calculated (Gain: (sample rate)/(2*π*deviation)).
There are several variations of the polar discriminator. This includes:
This concept looks at taking the frequency deviation of the FM signal and applying a process that will create an AM signal based on the deviation. There are two methods for this. (NOTE: I originally thought of them as unique; on review, they're really the same just with different methods to create the AM component.) These are slope detection and differentiate and envelope detection. Both methods add an AM component to the FM signal, then AM detect the signal. The only difference is how they create the AM component. The slope detector uses a filter; the differentiate-and-envelope detector uses a differentiator.
Both rely on a frequency offset from the complex center frequency of 0 Hz. The slope detection method offsets a filter from 0 Hz; the differentiate-and-envelope detection method offsets the signal from 0 Hz.
The idea of the slope detector is that we change the amplitude of the signal based on its instantaneous frequency using the slope of a filter . In other words, we add an amplitude modulation along with the frequency modulation. In other words, we make it both FM and AM at the same time. We create this effect by using a filter with a very wide transition width (the sloped part of the filter). The flowgraph appears as follows:
Slope detection requires the use of a filter with a wide transition width. The filter is a complex bandpass filter using complex taps. This allows for it to be offcenter in the spectrum. The lower transition band covers the FM signal, which after being filtered, is the sole signal centered at 0 Hz.
The result of this demodulator is shown below.
Comparing this demodulator with the polar discriminator above, it has (in my opinion) worse performance. If you look at the spectral display of the baseband output of the slope detector above, then compare it with the spectrum of the baseband from the polar discriminator, you see a lot more noise at the base of the 19 kHz pilot tone in the slope detector than from the polar discriminator. Further, adding an audio sink, the audio sounded worse (a slight noise present in the slope detector that was not present in the polar discriminator).
This method also adds an AM component to the FM signal, except it uses a differentiator to add the AM component as opposed to a filter as in the slope detector. The slope detector uses a filter that is offcenter from 0 Hz. In the differentiate-and-envelope detector, the signal is offcenter from 0 Hz before the differentiator is applied.
Why the offset? To understand that, we need to do a bit of math. The FM signal can be represented as the following complex signal:
If we differentiate this signal, we get the following:
where:
This differentiated signal is the same equation as a full-carrier, double-sideband AM signal. The value of ω is the carrier amplitude, while the value dθ/dt is the information. The value of ω must be at least equal to the value dθ/dt; otherwise, you'll get "sideband splatter" (distortion of the AM signal because the information causes the carrier to cross the zero line). This means that we need to set the offset at least equal to the deviation in order to not have distortion on our signal.
But we don't want the offset to be too high, either. As the offset (ω) increases, the ratio of the carrier amplitude to the information amplitude also increases. This, in turn, will reduce the modulation index of the AM signal. That means you'll wind up with a lower SNR at the output of the receiver. The best offset is right at the deviation value. This will get you 100% modulation index. The index drops as the value of the offset increases beyond the deviation.
Let's talk briefly about how we will achieve this frequency offset...
Remember how I said earlier that I've picked up a few things since my first posts on FM demodulators back in the dark ages of 2019? Here's one of those things. Rather than tuning the SDR directly to the frequency of the signal being demodulated, filtering it, then frequency shifting it, I'm simply going to tune my SDR offset from the signal center frequency, then filter using a bandpass filter. The output will be a signal whose center frequency is at some IF. The result is the same as if I had used the first method (tune directly to signal, filter, then frequency shift), only it saves the processing of creating the complex sinusoid and multiplying it with the incoming samples. As fred harris points out, the taps for the filter might have different values (due to the fact that I'm using complex taps for the bandpass filter vs the real taps of the lowpass filter), but the number of taps remains the same. This, in turn, means I'm not having to do any more processing for the bandpass vs lowpass filter. They're the same, processing-wise. This will be the method I use for this, the differentiate-and-envelope detection demodulator, as well as the delay line discriminator and the zero crossing discriminator, which I'll cover later.
Back to our differentiate-and-envelope detector. For this processing, I used the Lyons' 7-tap differentiator. To ensure that the differentiator stays within the linear portion of operation, the sample rate is not decimated after passing through the lowpass filter. The offset is just above the deviation (as discussed above) with an extra bit of offset to deal with noise.
The performance of this demodulator was slightly better than the slope detection method, perhaps because the differentiator is more linear than the slope of the filter, so that frequency changes map more closely to amplitude changes in the information signal. However, its performance will probably never match that of the phase difference methods for the reason posited by James Shima (my emphasis added):
The other issue with using the derivative formulation is that it is not as accurate as the atan version. Why? Because the first order difference in phase of the message is more accurate than the first order difference of the entire signal. In other words, for sinusoidal messages the atan version gives exact results for the true derivative, whereas this is not true for the derivative formulation you listed. As such, for more complex message signals atan version should show less error.
In other words, calculating the difference of the phase (phase differential) is a far more accurate demodulation method than calculating the difference of the entire signal (differential-and-envelope). Which explains why the differential-and-envelope method does not provide as clean a demodulation as does either the phase differential methods.
All told, the FM-to-AM conversion demodulators are probably the worst type of FM demodulators. Don't get me wrong; they work. Sort of. But they do not provide as clean a demodulation as the phase difference method. Further, there are some aspects that need to be tweaked. For example, both need a higher sample rate to ensure the differentiators work properly. The differentiate-and-envelope detector also needs its center frequency offset adjusted. These are things that do not exist in the phase difference methods.
A phase lock loop (PLL) is a circuit that uses feedback to lock to the frequency of a signal. One of the uses of such a circuit is to demodulate signals, specifically FM signals.
Normally, I would try to make a PLL in Gnu Radio using individual components. Unfortunately, GRC does not have a mechanism to allow feedback within a flowgraph. The good news is that it does have a PLL block that we can use, specifically the "PLL Frequency Detector" block. This block has three parameters. These are:
The nice thing about the "PLL Frequency Detector" block is that, just as with the "Quadrature Demod" block, it is the only block required for demodulation. However, unlike with the "Quadrature Demod" block, the "PLL Frequency Detector" needs a bit of help with the output amplitude. Therefore, a "Multiply Const" block right after will typically be needed if you wish to use it for display or other processing purposes.
Demodulation with the "PLL Frequency Detector" may be as good as the phase differential methods. However, as the output requires constant amplitude tweaking, I still prefer the more-consistent output of the phase differential methods.
These last two are special in that they require the signal to be changed from complex to real in order to work. Every other frequency demodulator works from complex samples, though the FM-to-AM methods will also work from real samples. This one and the next one (the zero crossing discriminator) only work only with real samples. That means that the FM signal has to be shifted to an IF, since a real-only signal cannot cross the 0 Hz or Nyquist frequency boundaries. If it does so, it will alias.
We create this IF using the same frequency shift method as with the differentiate-and-envelope detect method.
The concept of the delay line discriminator is this: if you multiply a sinusoid with another sinusoid that is the same amplitude and frequency, but 90o (π/2 radians) out of phase with the first sinusoid, you get another signal. This is a sinusoid at twice the frequency of the original sinusoids. But what if the two sinusoids are not precisely 90o out of phase? What if they are either slightly more or less than 90o? Then the product of the multiplication will be a DC component plus the sinusoid at twice the frequency. If we filter out the 2x frequency component (say with a lowpass filter), you're left with the DC component.
Here's the good news. The amplitude of the DC component will be determined by how far off from 90o the relative phase is. As the relative phase moves further away and closer to 90o, the amplitude of this DC component will change accordingly. We can use this concept to frequency demodulate a signal. The way in which we do this is to frequency shift the signal to an IF. Then we split the signal; one-half goes directly to a multiplier. The other half is delayed by 1/4 of a cycle of the IF. For example, if the IF is 200 kHz, it would have a period of 5 μsec. If we can delay the second half of the split signal by precisely 1/4 of this (1.25 μsec), we'll have our circuit.
The way this circuit works is as follows:
How do we implement this concept? Take the FM signal, frequency shift it to an intermediate frequency (IF), convert it to real, then multiply it with a delayed version of itself. It's the amount of delay that is important. We need a delay that is 1/4 cycle of the IF. The 1/4 cycle means the phase difference is 90o. This leads to needing a number of samples per cycle of the IF that is evenly divisible by 4. The number of samples per cycle cannot be too high, however. That's because the IF will be the sample rate divided by the samples per cycle. If you make the samples per cycle too high, the IF will be too low and the signal will be aliased once it is convered to real. There's also the filtering after the delay-and-multiplication. You also do not want any of the delayed-and-multiplied signal to fall within the lowpass filter passband. This means that the offset must be high enough that the frequency deviation is never less than 1/2 of the passband. Here's how I implemented this in Gnu Radio.
The results are not too shabby, though still not as good as the phase differential methods.
This is my favorite method, though it is also the most computationally-expensive one. I like it because it's fun. The concept is this: shift the signal to a IF, convert it from complex to real, then turn each zero crossing of the IF sinusoid into an impulse. Essentially count the impulses. VOILA! The signal is demodulated. Why? Because, due to the frequency modulation, as the signal swings above the center frequency, the period will drop. (Remember, kids: Frequency is the inverse of the period, and the period is the inverse of the frequency.) As the period drops, the impulses will get closer together. This means more of them in a set time. The inverse is true as the frequency swings lower than the center frequency, the number of impulses will drop. These impulses can be "counted" through the straightforward method of lowpass filtering.
The downside to this method (and the reason why it's not a good method for implementing digitally) is that creating the impulses is effectively quantizing the levels based on the sample rate and the IF. The lower the sample rate or the higher the IF, the fewer the quantizing levels. In order to get performance equivalent to the phase differential methods, you need a reeeeeally high sample rate or a reeeeeally low IF. You're limited by the bandwidth of the signal to how low the IF can be. The limit is 1/2 of the bandwidth. For a FM broadcast station, this would be roughly 100 kHz. (NOTE: In the US, the deviation allowed is 75 kHz, with some cases allowing up to 82 kHz.) The maximum sample rate would be whatever your system can handle. In total, this means that this method is not a good one if you're looking to try this on a Raspberry Pi (though perhaps one of the newer ones might be able to handle it).
Using this flowgraph with two, different "interp" values (a value used to increase the sample rate), the results show that a higher sample rate definitely improves the output signal.
Again, this is my favorite demodulator despite the fact that it is not really practical for any actual, real-world situation. It's much more complicated, requires a lot more processing, and still will not get to the same accuracy as one of the phase differential methods.
There you have it. Pretty much every FM demodulator possible using digital techniques. I'm going to consider this my "reference page" for all things FM demodulation from here on. If I come across another demodulator, I probably won't add a blog post. I'll just update this page and add that new technique here.
Til next time!
The end of the telephone line that plugs into the phone plug is called a jack. The reason is that it is named after the French-Canadian inventor, Mr. Jack.
ARRL - Amateur Radio Relay League
The New Horizons Interplanetary Explorer
NRL Monterey - Satellite Meteorology
WWdN: In Exile - Wil Wheaton Blog
Calculating Volume in Horizontal Tank
March 2025 - The Five Methods for Frequency Demodulation
January 2025 - Making a "Soft" Tuner & Receiver in Gnu Radio
December 2024 - Understanding the Polar Discriminator (Finally)
September 2024 - Decoding AIS Signals
June 2024 - Programming the Arduino - Part 2
June 2024 - Setting Up the HM2004A Liquid Crystal Display
April 2024 - An Aircraft Communication Receiver
February 2024 - A Review of Dave Rowntree's Gnu Radio FM Receiver
January 2024 - A Test of Different RDS Demods using Gnu Radio
November 2023 - An Overview of SDRconnect
August 2023 - SDRuno and the "Zero IF" vs "Low IF"
July 2023 - Gigabit Ethernet and the Misunderstanding of the Fifth Level
May 2023 - Rather Deep Overview of SDRangel
April 2023 - Creating a Variable RBW Spectral Display
January 2023 - Improvement to the Zero Crossing FM Discriminator
January 2023 - Differences of Hardware and Software Radios
December 2022 - Bandwidth Limits of the Tayloe Detector
September 2022 - Linux Mint 21 and Grub
July 2022 - NOAA APT with Gnu Radio - UPDATED
June 2022 - Playing Back IQ Files with Gnu Radio
May 2022 - Assassins Creed Odyssey - in 3D
January 2022 - Gnu Radio and AM Demodulation Overview
August 2021 - Gnu Radio and RBDS Demodulation
July 2021 - Gnu Radio and Amplitude Demodulation
June 2021 - Gnu Radio and Narrow Resolution Frequency Displays
April 2021 - Gnu Radio and Sample Rates
March 2021 - SDRs and Spectral Displays
February 2021 - Assassin's Creed: Boar War
December 2020 - Demodulating NOAA APT Signals
December 2020 - Understanding Gnu Radio Blocks - Filtering
November 2020 - Hak5 and Gnu Radio
August 2020 - Gnu Radio and FM Demod - Part 3
May 2020 - Gnu Radio and FM Demod - Part 2
November 2019 - To Delay and Conjugate, or Not?
November 2019 - Gnu Radio and FM Demod - Part 1
July 2019 - Linux Mint - An Update
December 2018 - Installing Arch Linux
October 2017 - Upgrading the PS4 Hard Drive
September 2017 - Flatbed Scanner for Linux
September 2017 - The Sony ICD-PX312 and Hold Problem
January 2017 - Fixing a Boot Issue with Linux Mint
November 2016 - Using a USB Thumb Drive in a Honda Accord
September 2016 - Scribd and Open Source Material
April 2016 - Comparing Computers over Time
February 2016 - ISS Night Photo and Google Earth
January 2016 - John Scalzi's 'Old Man's War'
October 2015 - Pat Robertson and Hurricane Joaquin
September 2015 - The Nagasaki A-Bomb
March 2015 - Indiana's 'Religious Freedom'
February 2015 - Apologies to Adafruit
February 2015 - Calculating Radiation Exposure - Take 2
January 2015 - Calculating Radiation Exposure
November 2014 - Programming the Arduino - Part 1
November 2014 - Understanding the LCM1602C LCD Display - Part 2
November 2014 - Understanding the LCM1602C LCD Display - Part 1
September 2014 - Sparkfun Digital Sandbox
December 2013 - Open Letter to Lawfare Blog
December 2013 - Airdroid and Ubuntu Permissions
April 2013 - PS3 and Notworking
January 2013 - Dosbox - Playing Tie Fighter
January 2013 - Old Post on New Computer - Updated
January 2013 - Dosbox - Playing Comanche 3
January 2013 - CSS and Background Images
October 2012 - Felix Baumgartner and Joe Kittinger
September 2012 - The Seagull Thief - Staged or Not
June 2012 - And Now... For Cute Prairie Dogs
June 2012 - Sharing Firefox Profiles between Windows and Ubuntu
May 2012 - "Have Fun. Murder Your Crew." - Redshirts has Arrived!
April 2012 - From Homeserver to Namecheap: The Short Story
April 2012 - Buh-BYE Homeserver
April 2012 - The Hidden Background: The Simple Method
April 2012 - The Hidden Background: A New Method
April 2012 - The Hidden Background: Expanded and Explained
April 2012 - How to Make a Hidden Background
February 2012 - The Apple Problem
October 2011 - When PSD Meets (Turkey) Vultures
October 2011 - Cellphone Keyboard Fail
August 2011 - The New Freemat Primer is Here!
July 2011 - The New Laptop Running Ubuntu
July 2011 - The Recent Server Crash
March 2011 - Creating an Anaglyph with Gimp
December 2010 - Changing the SSH Port for IPTables
December 2010 - Another Malware Infection Report
November 2010 - Good Night, Leslie Nielsen. RIP.
November 2010 - What Just Happened (Part Deux)...?
November 2010 - Mapping My House
November 2010 - What Just Happened...?
November 2010 - My Own Microwave Range
November 2010 - The End is Nearer for Windows
November 2010 - The State of My Data
September 2010 - Engineering Trivia
September 2010 - Finishing Up Looking at our Hardware in Linux
September 2010 - Calculating the Surface Temperature of the Sun
September 2010 - Looking At Your Hardware in Linux
September 2010 - Where Is This Site Now?
September 2010 - Where's This Site Going?
August 2010 - The Digital Television Primer
August 2010 - What? This Site Has Changed AGAIN?!?!
June 2010 - How NOT To Use Advertising in a Web Page
May 2010 - Comments on Solving the Gulf Oil Spill
May 2010 - Using Gimp to Create a Fadeout
October 2009 - The Switch to Linux: Accessing a Second Hard Drive
January 2009 - Understanding Multicasting
November 2008 - IE's Lack of CSS Support
November 2008 - The Engineer's Creed
October 2008 - How to Perform an FCC ID Search
October 2008 - What's in my name?
October 2008 - Setting the KEYTIME on an HP50g
October 2008 - How to Test Your Remote Control: Method #2
October 2008 - How to Test Your Remote Controls
October 2008 - Printing with the HP50g
October 2008 - Mission: Impossible Wallpapers
Want to send me an e-mail? Just use this e-mail address and remove the part that says "no spam".
schafer AT site2241 no spam DOT net