{"article":{"slug":"simulating-airband-am-radios","title":"Simulating Airband AM Radios","subtitle":null,"summary":"Simulating Airband AM Radios Warning: Contains many annoying sounds. In a slight departure from my usual code monkey content, let’s talk about airplanes! And radios!","content_type":"essay","language":"en","canonical_url":"https://bitbashing.io/am-radio.html","author":{"name":"Matt Kline","url":"https://bitbashing.io/about.html","person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Bit Bashing","url":"https://bitbashing.io","listing_slug":null,"listing":null},"topics":[{"name":"Hardware","slug":"hardware","url":"https://listedarticles.com/topics/hardware"},{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Systems Programming","slug":"systems-programming","url":"https://listedarticles.com/topics/systems-programming"},{"name":"Science","slug":"science","url":"https://listedarticles.com/topics/science"},{"name":"Tutorials","slug":"tutorials","url":"https://listedarticles.com/topics/tutorials"}],"about_listings":[],"cover_image_url":null,"license":"CC-BY-SA-4.0","word_count":3432,"reading_minutes":15,"published_at":"2026-06-19T00:00:00.000Z","added_at":"2026-09-29T12:23:14.770Z","updated_at":"2026-09-29T12:23:14.770Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/simulating-airband-am-radios","markdown_url":"https://listedarticles.com/articles/simulating-airband-am-radios.md","example":false,"citation":"Matt Kline, Bit Bashing. \"Simulating Airband AM Radios.\" 19 Jun 2026. https://bitbashing.io/am-radio.html (CC-BY-SA-4.0)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://bitbashing.io/am-radio.html"},"body_markdown":"# Simulating Airband AM Radios\n\n**Warning: Contains many annoying sounds.**\n\nIn a slight departure from my usual code monkey content, let’s talk about airplanes! And radios!\n\nFor the last several years, I’ve spent most Saturdays playing (and occasionally working on)\nBMS, a modern<sup>1</sup> combat flight sim where you\nand your friends blow stuff up in virtual F-16s.\nAny co-op game with over 30 people is a blast,\nbut air combat is especially fun because it’s such a team sport.\nFlights swirl in vicious dogfights and\nplay deadly games of whack-a-mole\nwith enemy air defenses, all just to give a few jets a couple of seconds over the target\nto drop their bombs.\nNone of it is scripted, and everyone has to work together to come back alive.\n\nYou might imagine this involves a lot of talking, and so BMS ships with a voice chat app called IVC. To add to the immersion, it simulates the radios in your virtual cockpit. You don’t join a chat room, you tune to a radio frequency. Your signal fades as your jet gets further from whoever you’re talking to, or if you’re both flying low, you can be blocked by terrain entirely.\n\nSurprisingly, airplane radios—even many military ones—are still simple AM sets that operate in the VHF and UHF bands. One of the reasons that’s persisted through decades of technological advances is that AM radio doesn’t have a “capture effect”. When two people transmit on the same frequency, you can still (sorta) hear both parties, unlike FM where the louder signal mutes or “captures” the quieter one. Here’s what it sounds like when fighter pilots talk over each other, captured during a Red Flag training exercise in Nevada:\n\nSo imagine my… curiosity when IVC just makes this sound whenever people step on each other:\n\nThat bugs me more than it should. So when a buddy set out to build an IVC replacement with better UX and modern audio codecs, I wanted to contribute some realistic AM radio dynamics. Like these:\n\nHow? Let’s dive in.\n\n## Radio 101: path loss, decibels, SNR\n\nSo you want to talk to someone over the radio.\nLet’s set aside the black magic of antenna design—take it as a given\nthat if you cut the right length of wire and wiggle the electrons in it,\nsome of them will magically shear off into space as electromagnetic waves.\nEven if those waves don’t run into anything,<sup>2</sup> they get weaker as a square of radius \nfrom the transmitting antenna, simply because they spread out as they travel.\n\nThis is true of all waves—sound, radio, light.<sup>3</sup>\nAnd because different distances from the source produce such wildly different power levels,\nour senses need to work on logarithmic scales.\nThey’re actually pretty astonishing—the roar of a jet engine is a million times louder\nthan the quietest whisper, and you can hear both.\nA room can be a million times darker than a sunny day, yet you can see in both.\n\nThe radio frequency (RF) world is no different. Because it would be annoying to work with such a wide range of numbers, we often describe signal strength in a logarithmic scale called decibels, abbreviated as dB. One of the first things we’d like to describe in decibels is the signal-to-noise ratio, or SNR.\n\nSome noise is man-made, some comes from atmospheric events like thunderstorms, and some comes from outer space. More noise comes from the imperfections in your radio’s electrical components. And even if you could somehow remove all of those noises, you’d still hear thermal energy vibrating the electrons in your receiver. (We call this phenomenon thermal noise and it’s our theoretical minimum.)\n\nBut no matter where it comes from, noise is always there! We can never get rid of it; we only hope the received signal is louder than the noise by the time it reaches us.\n\n## Amplitude modulation\n\nSo what waves should you broadcast?\nThe frequencies that make up your voice (and everything else you hear) are between\n20 and 20,000 cycles per second, or Hertz.\nBut the lower the frequency, the longer the wavelength,\nand good antennas are at least a quarter of the wavelength they receive.\nTo pick up a 10 kHz signal, we’d need over 7 kilometers of wire.<sup>4</sup>\n\nInstead, let’s shift our voice onto some higher *carrier* frequency\nthat we can actually transmit.\nA simple approach is to modulate the carrier wave’s amplitude by that of our voice.\nWe might call this *amplitude modulation*, or AM for short.\n\nNotice how the outlined shape of the resulting AM signal—its *envelope*—is a\nmirrored copy of our voice. Hmm…\n\n## What’s in a radio?\n\nGlossing over how you *tune* your radio to different frequencies\n(the answer might shock you!),\nwe have a few other problems to solve if we want to hear an AM signal:\n\n1. \n    We need to filter out all the frequencies we don’t care about, passing only the band of frequencies we actually want. (Let’s call that the *passband.* )\n2. \n    The signal is probably very weak by the time we get it (see above), so we need to amplify it.\n3. \n    Lastly, we use an *envelope detector* to extract, or*demodulate* ,\nour voice back out of the AM signal.\n\n### Filtering\n\nHow do we let some frequencies through and block others out? Let’s talk circuits 101.\n\nIn the analog world, we deal in:\n\n- *Current (I)* , which represents electrons flowing through our circuit\n- *Voltage (V)* , which represents the electric potential energy between two parts of a circuit, and\n- *Resistance (R)* , which represents the reluctance of some part of a circuit to let current flow through it.\n\nThey can behave in unintuitive ways, but they are always proportional to each other according to Ohm’s law:\n\nWith this knowledge, we can make one of the simplest useful analog circuits: a voltage divider.\n\nThe squiggly bits represent *resistors*,\nand the inverted dashed triangle at the bottom represents *ground*, or 0 volts,\nto which we compare all our other voltages.\nBecause resistors oppose the flow of current,\nour output voltage will be some fraction of the input voltage,\nbased on the ratio of the two resistors.\nDrag the slider to change that ratio,\nand observe how:\n\nWhat if we swap out one of the resistors for something more interesting?\n\nThis symbol represents a *capacitor*,\na part that stores electric charge between two plates, and can discharge it later.\nIf we swap  out for one, we get the behavior:\n\nAs time  goes by,  asymptotically approaches \nat a rate determined by the resistance  multiplied by the capacitance .\nBecause of this, we call  the *time constant*, or .\nA little more math shows us that every , the voltage advances 95% of the way\nfrom  to , where  is just whatever our starting voltage was.\n\nThis makes capacitors useful for all sorts of applications,\nbut the thing we care about today is how one behaves when given an alternating input\n(like a wave from an antenna!) instead of a constant one.\nBecause the capacitor is constantly charging and discharging,\nits resistance<sup>5</sup> decreases as frequency increases.\nThis makes our RC circuit a *low-pass filter* that lets low frequencies through and\nshrinks—or *attenuates*—high frequencies.\n\nAnd if we just swap the resistor and capacitor, we have a high-pass filter. Instead of the capacitor shunting high frequencies to ground, it’s letting high frequencies through from , and so low frequencies are attenuated.\n\nFilter design can get amazingly complex—there are whole textbooks on this stuff—but the basics don’t have to be. We’ll find that it’s surprisingly easy to do this in the digital world as well.\n\n### Automatic gain control\n\nWe also need to amplify our signal.\nBut how much?\nEven though we’ll receive signals with wildly different strengths,\nit would be great if our radio had a consistent volume level when someone is talking.\nWe want to control the amplification, or *gain*, automatically.\n\nHow do we do that? More filters! If we take the magnitude of our signal, then low-pass it, we end up with a curve that gives a rough measure of its volume.\n\nWe have a slight conundrum, though—we want the filter to respond quickly when someone\nstarts talking, but to taper off slowly, so that the measured volume doesn’t drop\nwhenever they pause to take a breath. To do this we build a filter that responds differently\nwhen the signal rises (call this *attack*) and when the signal falls (call this *decay*).\n\nI also added a period of silence to our AM transmission—after all, pilots aren’t talking on the radio 100% of the time. Try moving the sliders around until the filtered magnitude:\n\n- Rises to the peak volume quickly when a transmission starts\n- Stays flat-ish for the entire transmission, but\n- Decays back to 0 quickly-ish when the transmission stops\n\nAnd lo, you’ve measured the volume of our signal! If we divide whatever comes in by this value, the user should always hear a similar volume.\n\n### AM demodulation\n\nNotice how if you drag the sliders around some more, we get something that looks suspiciously like the envelope. In fact, this sort of filter is sometimes called an “envelope detector”. To demodulate our AM signal back into the transmitted voice, we just need to low-pass the signal with one of them.\n\n### Squelch\n\nScroll back up to our SNR demo, and drag the slider all the way to the left\nuntil you hear only static.\nIsn’t that unpleasant?\nNobody likes hearing static for extended periods of time,\nso radios quickly grew a feature called *squelch*,\nwhich mutes your speakers whenever the signal falls below a certain volume.\nGood thing we just came up with a way to measure it!\n\nDrag the sliders around and consider some of the interesting effects going on:\n\n1. \n    When you turn the SNR down to about 0 dB, our transmission is no louder than the noise, and the squelch gate mutes us. But turn down the squelch threshold and you can still make things out! For this reason, some radios provide a way to disable squelch so you can listen to weak signals.\n2. \n    If you’ve listened to airband radios before, you’re probably familiar with a “click” when someone starts talking and a “kssh” when they stop. This isn’t some artificial sound effect—it’s a natural product of the interplay between AGC and squelch. As a transmission starts and the measured volume shoots above the noise floor, the squelch gate flies open as AGC quickly moves to attenuate the signal. The resulting pop, constrained by our bandwidth, softens to a clicking noise. (Try it with and without the bandpass.) Then, when the transmission stops, AGC rapidly turns the volume back up, so we hear the static rush in before the squelch gate clicks back off.\n\nWhenever you’re done with the demo, just drag squelch back up above the noise floor. Remember, noise is always there!\n\n## Interference\n\nWith those basics out of the way, let’s get back to that interference we hear when several folks talk at once. Where do all those funny noises come from?\n\nWe don’t live in an ideal world, and our electronics are no exception.\nIf I tune my radio to 121.5 MHz, its carrier frequency is oscillating back and forth\n121.5 *million* times a second. That’s pretty impressive!\nBut I shouldn’t be surprised if it’s not *exactly* that many Hertz.\nWithout very expensive machinery, electronic oscillators drift a little bit,\nespecially as they heat and cool (which airplanes tend to do when they fly around).\n\nAdditionally, whenever someone is moving, the Doppler Effect shifts the frequency of anything they transmit. If they’re going several hundred knots in a fighter jet, this shift can be substantial. (In fact, one of the revolutions in airborne radars was to measure this frequency shift, and use it to separate a plane on the radar screen from all the background clutter behind it. A fun story for another day!)\n\nWhat’s really neat is that an AM receiver usually doesn’t care. If you think you’re tuned to 121.5 MHz, but you’re actually on 121.4999 MHz, or receiving a signal at 121.5001 MHz, the envelope detector still demodulates the exact same envelope, and we’re good to go. That is until several people start talking.\n\nWhenever frequency  is played at the same time as frequency ,\nthey create a *beat frequency* at .\n\nYou’ve heard this yourself if you’ve ever tuned a musical instrument.\n\nThis same effect occurs with our imperfectly-tuned radios—while the carrier frequencies themselves are hundreds of times higher than the bandwidths of both the radio and your ears, the beats are not! One transmitter at 121.499 MHz and another at 121.501 MHz gives us a very audible, and very annoying, 2 kHz whine. You can listen to it and other example tones at https://www.szynalski.com/tone-generator/.\n\nThese beats also cause strange things to happen to the envelope:\n\n- \n    Voices are ring-modulated by the beat frequencies. (Think Daleks.)\n- \n    Louder voices amplitude modulate weaker ones.\n- \n    In severe cases, the envelope rises and falls rapidly, causing the AGC to rapidly “pump” the volume.\n\nWe’ll see why soon.\n\n## Again! But with computer!\n\nNext we need to make a computer do all of that.\n\nFor starters, computers (except the quantum ones) don’t deal in continuous\nanalog values. Instead, when we want to record some audio,\nan *analog-to-digital converter* samples the voltage\nof a microphone over and over, thousands of times a second,\ninto numbers that form a connect-the-dots representation of the sound waves.\nYour computer can also do the opposite—a\n*digital-to-analog* converter can turn a big list of numbers back into voltages that\nshake the diaphragm of your speakers.\nIf we want to do any *digital signal processing* in between,\nwe’re just transforming long lists of numbers into slightly different lists of numbers.\n\nAbout 100 years ago, some very smart people figured out you need double the sample rate of the frequencies you care to represent.\n\nAnd since human hearing tops out around 20 kHz,\nsample rates of 44.1 kHz<sup>6</sup> and 48 kHz are common for digital audio.\nThis is fortunate for us because “48 thousand times a second” is pretty trivial on a modern CPU.\n\n### Filtering\n\nRecall the voltage equation for our RC filter:\n\nIt doesn’t look too different in the digital world, where given some list of samples , each output is calculated from the current sample and the previous output:\n\nwhere for a sample period , or sample rate\n\nIf you want an envelope filter with separate attack and decay coefficients, pick a different depending on whether . We’ll use this for our AGC.\n\nJust like in the analog world, digital filter design can get much more complicated, but we can start here.\n\n### IQ sampling\n\nIn a similar way, we can directly calculate the sound of multiple transmitters interfering\nwith each other.\nBut to do that, we need to chat some more about how we represent frequencies\nin the first place. All the waves we’ve looked at so far have been a single sinusoid\nwiggling up and down. That’s a simple representation,\nbut it’s a bit lacking.\nFor starters, it’s *ambiguous*—at most points in time,\nyou can’t determine the *phase* of the signal.\n\nWhat if instead we represented a frequency with *two* sinusoids—both a cosine *and* a sine?\n\nBecause the sine wave is a quarter cycle behind the cosine,\nwe often call this representation “in-phase and **quad**rature encoding”,\nor IQ for short.\n\nSo instead of thinking about a frequency as a single wave moving up and down at a given rate,\nimagine it as a *phasor* spinning around at that rate:\n\nPhasors can also spin the opposite way, giving us a *negative* frequency.\nIf this notion seems weird and scary to you, you’re not alone!\nIt was a long time before *any* negative numbers stopped seeming weird to mathematicians.\n\nSince RF engineers work with IQ a *lot*,\nthey want a more concise way to express phasors.\nIf we turn a phasor into a complex number,\nthen we can use Euler’s formula to represent it as a single term,\n raised to an imaginary<sup>7</sup> exponent:\n\n(In the electrical engineering world, we use instead of because represents current.)\n\nWe won’t use that formulation much today, but it’s everywhere in the signal processing world. If you want to learn more, check out the DSP GOAT Richard Lyons’s explanation, Quadrature Signals: Complex, But Not Complicated.\n\n### A baseband AM simulation\n\nNow we’re ready to put it all together.\nWe’re going to simulate our AM radios in *baseband*—i.e.,\nonly the audio frequencies that would be demodulated by the envelope detector.\nThe main reason for this is that a *full band* simulation of the carrier frequencies\nat over 100 MHz would be difficult to do in real time,\nsince we’d have to process hundreds of millions of samples each second.\n\nFor  radios transmitting at once on carrier frequencies\n,\nwe’ll make a list of *relative* frequencies .\nNote how an arbitrary frequency—the first in our list, —becomes our “zero” frequency.\nIn the digital world with a sample rate , this means our phase angle for each is:\n\nWe can then represent each of our signals as a product of that phasor, its , and its samples multiplied by our modulation index .\n\nThe single signal case is pretty boring: , and since and , this simplifies to:\n\nSubsequent transmitters get a bit more interesting. Their phase isn’t 0—instead it’s rotating at . For example, if our first signal had a 100 MHz carrier and our second had a 100.002 MHz carrier, we’d get a rotating at 2 kHz. Repeat this for each transmitter, throw in some random noise for good measure, and all of these IQ vectors sum to\n\nOur audible envelope is just the length of that IQ vector:\n\n.\n\nIf you plot this out, you start to see the wackiness. While the first signal—which we’re calculating everything relative to—is always in-phase with itself, the other signals constantly shift in phase, producing the effects we discussed earlier.\n\nFeed that into our AGC filter, squelch the output when is less than our threshold, apply a bandpass filter to limit it to AM bandwidths (about 300 Hz to 3–5 kHz), and we’re done! The results sound pretty cool. Here’s a snippet from an old demo:\n\nWhat’s even cooler is that there’s not a lot to tweak. Our only real inputs are:\n\n- Our signals and their relative strengths\n- Some randomly-generated noise\n- Attack and decay constants for our AGC\n- Upper and lower band limits for our bandpass filter\n\nAnd from that we get a simulation that 4 out of 4 ~~dentists~~ pilots\nsay sounds just like the real deal.\nI think there’s a valuable lesson there—while your sim will never be *exactly* like real life,\nyou can get surprisingly close with surprisingly little code if you sit and think about\nthe problem from first principles.\n\nYou can grab a copy of that demo app to mess around here, or check out the actual code here. Cheers!\n\n1. \n      As opposed to World War II sims like IL-2, “modern” here mostly just means “has jets and missiles”, focusing especially on the 1980s–2000s. I get annoyed when BMS and its genre sibling DCS try to add newer planes, weapons, and scenarios—they’re inherently less fun (as air combat shifts towards standoff weapons instead of dogfights/watching things explode) and increasingly made up (due to an obvious lack of public information on modern air combat). \nBut that’s a rant for another day. ↩\n2. \n      OpenFreq also does line-of-sight checks and applies some interesting math when signals graze the terrain at shallow angles. But that’s mostly just an exercise in ray tracing. Maybe we’ll chat about it some other time. ↩\n3. \n      Watch this if you’d like to ruminate on it more. ↩\n4. \n      …not that it stops superpowers from building them to talk to underwater submarines. Welcome to the sci-fi world of *extremely low frequency* comms. ↩\n5. \n      Well, impedance, electrical nerd for “resistance that can change over time or over frequency” ↩\n6. \n      If you’re wondering where the extra 4.1 kHz comes from, it was chosen in the late 1970s for CD audio to give filters a little extra headroom. ↩\n7. \n      Not so fun fact: The term “imaginary numbers” was coined by Descartes as a complaint about how useless he thought they were. Euler would prove him quite wrong in the next century, yet we still use Descartes’s insult to describe roots of -1. I was in my 30s before someone taught me how nice complex numbers are for representing rotations and frequencies, like we’re talking about today. ↩","body_html":"<h1 id=\"simulating-airband-am-radios\">Simulating Airband AM Radios</h1>\n<p><strong>Warning: Contains many annoying sounds.</strong></p>\n<p>In a slight departure from my usual code monkey content, let’s talk about airplanes! And radios!</p>\n<p>For the last several years, I’ve spent most Saturdays playing (and occasionally working on)\nBMS, a modern&lt;sup&gt;1&lt;/sup&gt; combat flight sim where you\nand your friends blow stuff up in virtual F-16s.\nAny co-op game with over 30 people is a blast,\nbut air combat is especially fun because it’s such a team sport.\nFlights swirl in vicious dogfights and\nplay deadly games of whack-a-mole\nwith enemy air defenses, all just to give a few jets a couple of seconds over the target\nto drop their bombs.\nNone of it is scripted, and everyone has to work together to come back alive.</p>\n<p>You might imagine this involves a lot of talking, and so BMS ships with a voice chat app called IVC. To add to the immersion, it simulates the radios in your virtual cockpit. You don’t join a chat room, you tune to a radio frequency. Your signal fades as your jet gets further from whoever you’re talking to, or if you’re both flying low, you can be blocked by terrain entirely.</p>\n<p>Surprisingly, airplane radios—even many military ones—are still simple AM sets that operate in the VHF and UHF bands. One of the reasons that’s persisted through decades of technological advances is that AM radio doesn’t have a “capture effect”. When two people transmit on the same frequency, you can still (sorta) hear both parties, unlike FM where the louder signal mutes or “captures” the quieter one. Here’s what it sounds like when fighter pilots talk over each other, captured during a Red Flag training exercise in Nevada:</p>\n<p>So imagine my… curiosity when IVC just makes this sound whenever people step on each other:</p>\n<p>That bugs me more than it should. So when a buddy set out to build an IVC replacement with better UX and modern audio codecs, I wanted to contribute some realistic AM radio dynamics. Like these:</p>\n<p>How? Let’s dive in.</p>\n<h2 id=\"radio-101-path-loss-decibels-snr\">Radio 101: path loss, decibels, SNR</h2>\n<p>So you want to talk to someone over the radio.\nLet’s set aside the black magic of antenna design—take it as a given\nthat if you cut the right length of wire and wiggle the electrons in it,\nsome of them will magically shear off into space as electromagnetic waves.\nEven if those waves don’t run into anything,&lt;sup&gt;2&lt;/sup&gt; they get weaker as a square of radius \nfrom the transmitting antenna, simply because they spread out as they travel.</p>\n<p>This is true of all waves—sound, radio, light.&lt;sup&gt;3&lt;/sup&gt;\nAnd because different distances from the source produce such wildly different power levels,\nour senses need to work on logarithmic scales.\nThey’re actually pretty astonishing—the roar of a jet engine is a million times louder\nthan the quietest whisper, and you can hear both.\nA room can be a million times darker than a sunny day, yet you can see in both.</p>\n<p>The radio frequency (RF) world is no different. Because it would be annoying to work with such a wide range of numbers, we often describe signal strength in a logarithmic scale called decibels, abbreviated as dB. One of the first things we’d like to describe in decibels is the signal-to-noise ratio, or SNR.</p>\n<p>Some noise is man-made, some comes from atmospheric events like thunderstorms, and some comes from outer space. More noise comes from the imperfections in your radio’s electrical components. And even if you could somehow remove all of those noises, you’d still hear thermal energy vibrating the electrons in your receiver. (We call this phenomenon thermal noise and it’s our theoretical minimum.)</p>\n<p>But no matter where it comes from, noise is always there! We can never get rid of it; we only hope the received signal is louder than the noise by the time it reaches us.</p>\n<h2 id=\"amplitude-modulation\">Amplitude modulation</h2>\n<p>So what waves should you broadcast?\nThe frequencies that make up your voice (and everything else you hear) are between\n20 and 20,000 cycles per second, or Hertz.\nBut the lower the frequency, the longer the wavelength,\nand good antennas are at least a quarter of the wavelength they receive.\nTo pick up a 10 kHz signal, we’d need over 7 kilometers of wire.&lt;sup&gt;4&lt;/sup&gt;</p>\n<p>Instead, let’s shift our voice onto some higher <em>carrier</em> frequency\nthat we can actually transmit.\nA simple approach is to modulate the carrier wave’s amplitude by that of our voice.\nWe might call this <em>amplitude modulation</em>, or AM for short.</p>\n<p>Notice how the outlined shape of the resulting AM signal—its <em>envelope</em>—is a\nmirrored copy of our voice. Hmm…</p>\n<h2 id=\"what-s-in-a-radio\">What’s in a radio?</h2>\n<p>Glossing over how you <em>tune</em> your radio to different frequencies\n(the answer might shock you!),\nwe have a few other problems to solve if we want to hear an AM signal:</p>\n<ol><li><p></p><p>  We need to filter out all the frequencies we don’t care about, passing only the band of frequencies we actually want. (Let’s call that the <em>passband.</em> )</p></li><li><p></p><p>  The signal is probably very weak by the time we get it (see above), so we need to amplify it.</p></li><li><p></p><p>  Lastly, we use an <em>envelope detector</em> to extract, or<em>demodulate</em> ,\nour voice back out of the AM signal.</p></li></ol>\n<h3 id=\"filtering\">Filtering</h3>\n<p>How do we let some frequencies through and block others out? Let’s talk circuits 101.</p>\n<p>In the analog world, we deal in:</p>\n<ul><li><em>Current (I)</em> , which represents electrons flowing through our circuit</li><li><em>Voltage (V)</em> , which represents the electric potential energy between two parts of a circuit, and</li><li><em>Resistance (R)</em> , which represents the reluctance of some part of a circuit to let current flow through it.</li></ul>\n<p>They can behave in unintuitive ways, but they are always proportional to each other according to Ohm’s law:</p>\n<p>With this knowledge, we can make one of the simplest useful analog circuits: a voltage divider.</p>\n<p>The squiggly bits represent <em>resistors</em>,\nand the inverted dashed triangle at the bottom represents <em>ground</em>, or 0 volts,\nto which we compare all our other voltages.\nBecause resistors oppose the flow of current,\nour output voltage will be some fraction of the input voltage,\nbased on the ratio of the two resistors.\nDrag the slider to change that ratio,\nand observe how:</p>\n<p>What if we swap out one of the resistors for something more interesting?</p>\n<p>This symbol represents a <em>capacitor</em>,\na part that stores electric charge between two plates, and can discharge it later.\nIf we swap  out for one, we get the behavior:</p>\n<p>As time  goes by,  asymptotically approaches \nat a rate determined by the resistance  multiplied by the capacitance .\nBecause of this, we call  the <em>time constant</em>, or .\nA little more math shows us that every , the voltage advances 95% of the way\nfrom  to , where  is just whatever our starting voltage was.</p>\n<p>This makes capacitors useful for all sorts of applications,\nbut the thing we care about today is how one behaves when given an alternating input\n(like a wave from an antenna!) instead of a constant one.\nBecause the capacitor is constantly charging and discharging,\nits resistance&lt;sup&gt;5&lt;/sup&gt; decreases as frequency increases.\nThis makes our RC circuit a <em>low-pass filter</em> that lets low frequencies through and\nshrinks—or <em>attenuates</em>—high frequencies.</p>\n<p>And if we just swap the resistor and capacitor, we have a high-pass filter. Instead of the capacitor shunting high frequencies to ground, it’s letting high frequencies through from , and so low frequencies are attenuated.</p>\n<p>Filter design can get amazingly complex—there are whole textbooks on this stuff—but the basics don’t have to be. We’ll find that it’s surprisingly easy to do this in the digital world as well.</p>\n<h3 id=\"automatic-gain-control\">Automatic gain control</h3>\n<p>We also need to amplify our signal.\nBut how much?\nEven though we’ll receive signals with wildly different strengths,\nit would be great if our radio had a consistent volume level when someone is talking.\nWe want to control the amplification, or <em>gain</em>, automatically.</p>\n<p>How do we do that? More filters! If we take the magnitude of our signal, then low-pass it, we end up with a curve that gives a rough measure of its volume.</p>\n<p>We have a slight conundrum, though—we want the filter to respond quickly when someone\nstarts talking, but to taper off slowly, so that the measured volume doesn’t drop\nwhenever they pause to take a breath. To do this we build a filter that responds differently\nwhen the signal rises (call this <em>attack</em>) and when the signal falls (call this <em>decay</em>).</p>\n<p>I also added a period of silence to our AM transmission—after all, pilots aren’t talking on the radio 100% of the time. Try moving the sliders around until the filtered magnitude:</p>\n<ul><li>Rises to the peak volume quickly when a transmission starts</li><li>Stays flat-ish for the entire transmission, but</li><li>Decays back to 0 quickly-ish when the transmission stops</li></ul>\n<p>And lo, you’ve measured the volume of our signal! If we divide whatever comes in by this value, the user should always hear a similar volume.</p>\n<h3 id=\"am-demodulation\">AM demodulation</h3>\n<p>Notice how if you drag the sliders around some more, we get something that looks suspiciously like the envelope. In fact, this sort of filter is sometimes called an “envelope detector”. To demodulate our AM signal back into the transmitted voice, we just need to low-pass the signal with one of them.</p>\n<h3 id=\"squelch\">Squelch</h3>\n<p>Scroll back up to our SNR demo, and drag the slider all the way to the left\nuntil you hear only static.\nIsn’t that unpleasant?\nNobody likes hearing static for extended periods of time,\nso radios quickly grew a feature called <em>squelch</em>,\nwhich mutes your speakers whenever the signal falls below a certain volume.\nGood thing we just came up with a way to measure it!</p>\n<p>Drag the sliders around and consider some of the interesting effects going on:</p>\n<ol><li><p></p><p>  When you turn the SNR down to about 0 dB, our transmission is no louder than the noise, and the squelch gate mutes us. But turn down the squelch threshold and you can still make things out! For this reason, some radios provide a way to disable squelch so you can listen to weak signals.</p></li><li><p></p><p>  If you’ve listened to airband radios before, you’re probably familiar with a “click” when someone starts talking and a “kssh” when they stop. This isn’t some artificial sound effect—it’s a natural product of the interplay between AGC and squelch. As a transmission starts and the measured volume shoots above the noise floor, the squelch gate flies open as AGC quickly moves to attenuate the signal. The resulting pop, constrained by our bandwidth, softens to a clicking noise. (Try it with and without the bandpass.) Then, when the transmission stops, AGC rapidly turns the volume back up, so we hear the static rush in before the squelch gate clicks back off.</p></li></ol>\n<p>Whenever you’re done with the demo, just drag squelch back up above the noise floor. Remember, noise is always there!</p>\n<h2 id=\"interference\">Interference</h2>\n<p>With those basics out of the way, let’s get back to that interference we hear when several folks talk at once. Where do all those funny noises come from?</p>\n<p>We don’t live in an ideal world, and our electronics are no exception.\nIf I tune my radio to 121.5 MHz, its carrier frequency is oscillating back and forth\n121.5 <em>million</em> times a second. That’s pretty impressive!\nBut I shouldn’t be surprised if it’s not <em>exactly</em> that many Hertz.\nWithout very expensive machinery, electronic oscillators drift a little bit,\nespecially as they heat and cool (which airplanes tend to do when they fly around).</p>\n<p>Additionally, whenever someone is moving, the Doppler Effect shifts the frequency of anything they transmit. If they’re going several hundred knots in a fighter jet, this shift can be substantial. (In fact, one of the revolutions in airborne radars was to measure this frequency shift, and use it to separate a plane on the radar screen from all the background clutter behind it. A fun story for another day!)</p>\n<p>What’s really neat is that an AM receiver usually doesn’t care. If you think you’re tuned to 121.5 MHz, but you’re actually on 121.4999 MHz, or receiving a signal at 121.5001 MHz, the envelope detector still demodulates the exact same envelope, and we’re good to go. That is until several people start talking.</p>\n<p>Whenever frequency  is played at the same time as frequency ,\nthey create a <em>beat frequency</em> at .</p>\n<p>You’ve heard this yourself if you’ve ever tuned a musical instrument.</p>\n<p>This same effect occurs with our imperfectly-tuned radios—while the carrier frequencies themselves are hundreds of times higher than the bandwidths of both the radio and your ears, the beats are not! One transmitter at 121.499 MHz and another at 121.501 MHz gives us a very audible, and very annoying, 2 kHz whine. You can listen to it and other example tones at <a href=\"https://www.szynalski.com/tone-generator/\" rel=\"nofollow ugc noopener\">https://www.szynalski.com/tone-generator/</a>.</p>\n<p>These beats also cause strange things to happen to the envelope:</p>\n<ul><li><p></p><p>  Voices are ring-modulated by the beat frequencies. (Think Daleks.)</p></li><li><p></p><p>  Louder voices amplitude modulate weaker ones.</p></li><li><p></p><p>  In severe cases, the envelope rises and falls rapidly, causing the AGC to rapidly “pump” the volume.</p></li></ul>\n<p>We’ll see why soon.</p>\n<h2 id=\"again-but-with-computer\">Again! But with computer!</h2>\n<p>Next we need to make a computer do all of that.</p>\n<p>For starters, computers (except the quantum ones) don’t deal in continuous\nanalog values. Instead, when we want to record some audio,\nan <em>analog-to-digital converter</em> samples the voltage\nof a microphone over and over, thousands of times a second,\ninto numbers that form a connect-the-dots representation of the sound waves.\nYour computer can also do the opposite—a\n<em>digital-to-analog</em> converter can turn a big list of numbers back into voltages that\nshake the diaphragm of your speakers.\nIf we want to do any <em>digital signal processing</em> in between,\nwe’re just transforming long lists of numbers into slightly different lists of numbers.</p>\n<p>About 100 years ago, some very smart people figured out you need double the sample rate of the frequencies you care to represent.</p>\n<p>And since human hearing tops out around 20 kHz,\nsample rates of 44.1 kHz&lt;sup&gt;6&lt;/sup&gt; and 48 kHz are common for digital audio.\nThis is fortunate for us because “48 thousand times a second” is pretty trivial on a modern CPU.</p>\n<h3 id=\"filtering-2\">Filtering</h3>\n<p>Recall the voltage equation for our RC filter:</p>\n<p>It doesn’t look too different in the digital world, where given some list of samples , each output is calculated from the current sample and the previous output:</p>\n<p>where for a sample period , or sample rate</p>\n<p>If you want an envelope filter with separate attack and decay coefficients, pick a different depending on whether . We’ll use this for our AGC.</p>\n<p>Just like in the analog world, digital filter design can get much more complicated, but we can start here.</p>\n<h3 id=\"iq-sampling\">IQ sampling</h3>\n<p>In a similar way, we can directly calculate the sound of multiple transmitters interfering\nwith each other.\nBut to do that, we need to chat some more about how we represent frequencies\nin the first place. All the waves we’ve looked at so far have been a single sinusoid\nwiggling up and down. That’s a simple representation,\nbut it’s a bit lacking.\nFor starters, it’s <em>ambiguous</em>—at most points in time,\nyou can’t determine the <em>phase</em> of the signal.</p>\n<p>What if instead we represented a frequency with <em>two</em> sinusoids—both a cosine <em>and</em> a sine?</p>\n<p>Because the sine wave is a quarter cycle behind the cosine,\nwe often call this representation “in-phase and <strong>quad</strong>rature encoding”,\nor IQ for short.</p>\n<p>So instead of thinking about a frequency as a single wave moving up and down at a given rate,\nimagine it as a <em>phasor</em> spinning around at that rate:</p>\n<p>Phasors can also spin the opposite way, giving us a <em>negative</em> frequency.\nIf this notion seems weird and scary to you, you’re not alone!\nIt was a long time before <em>any</em> negative numbers stopped seeming weird to mathematicians.</p>\n<p>Since RF engineers work with IQ a <em>lot</em>,\nthey want a more concise way to express phasors.\nIf we turn a phasor into a complex number,\nthen we can use Euler’s formula to represent it as a single term,\n raised to an imaginary&lt;sup&gt;7&lt;/sup&gt; exponent:</p>\n<p>(In the electrical engineering world, we use instead of because represents current.)</p>\n<p>We won’t use that formulation much today, but it’s everywhere in the signal processing world. If you want to learn more, check out the DSP GOAT Richard Lyons’s explanation, Quadrature Signals: Complex, But Not Complicated.</p>\n<h3 id=\"a-baseband-am-simulation\">A baseband AM simulation</h3>\n<p>Now we’re ready to put it all together.\nWe’re going to simulate our AM radios in <em>baseband</em>—i.e.,\nonly the audio frequencies that would be demodulated by the envelope detector.\nThe main reason for this is that a <em>full band</em> simulation of the carrier frequencies\nat over 100 MHz would be difficult to do in real time,\nsince we’d have to process hundreds of millions of samples each second.</p>\n<p>For  radios transmitting at once on carrier frequencies\n,\nwe’ll make a list of <em>relative</em> frequencies .\nNote how an arbitrary frequency—the first in our list, —becomes our “zero” frequency.\nIn the digital world with a sample rate , this means our phase angle for each is:</p>\n<p>We can then represent each of our signals as a product of that phasor, its , and its samples multiplied by our modulation index .</p>\n<p>The single signal case is pretty boring: , and since and , this simplifies to:</p>\n<p>Subsequent transmitters get a bit more interesting. Their phase isn’t 0—instead it’s rotating at . For example, if our first signal had a 100 MHz carrier and our second had a 100.002 MHz carrier, we’d get a rotating at 2 kHz. Repeat this for each transmitter, throw in some random noise for good measure, and all of these IQ vectors sum to</p>\n<p>Our audible envelope is just the length of that IQ vector:</p>\n<p>.</p>\n<p>If you plot this out, you start to see the wackiness. While the first signal—which we’re calculating everything relative to—is always in-phase with itself, the other signals constantly shift in phase, producing the effects we discussed earlier.</p>\n<p>Feed that into our AGC filter, squelch the output when is less than our threshold, apply a bandpass filter to limit it to AM bandwidths (about 300 Hz to 3–5 kHz), and we’re done! The results sound pretty cool. Here’s a snippet from an old demo:</p>\n<p>What’s even cooler is that there’s not a lot to tweak. Our only real inputs are:</p>\n<ul><li>Our signals and their relative strengths</li><li>Some randomly-generated noise</li><li>Attack and decay constants for our AGC</li><li>Upper and lower band limits for our bandpass filter</li></ul>\n<p>And from that we get a simulation that 4 out of 4 <del>dentists</del> pilots\nsay sounds just like the real deal.\nI think there’s a valuable lesson there—while your sim will never be <em>exactly</em> like real life,\nyou can get surprisingly close with surprisingly little code if you sit and think about\nthe problem from first principles.</p>\n<p>You can grab a copy of that demo app to mess around here, or check out the actual code here. Cheers!</p>\n<ol><li><p></p><pre><code>As opposed to World War II sims like IL-2, “modern” here mostly just means “has jets and missiles”, focusing especially on the 1980s–2000s. I get annoyed when BMS and its genre sibling DCS try to add newer planes, weapons, and scenarios—they’re inherently less fun (as air combat shifts towards standoff weapons instead of dogfights/watching things explode) and increasingly made up (due to an obvious lack of public information on modern air combat). </code></pre>\n<p>But that’s a rant for another day. ↩</p></li><li><p></p><pre><code>OpenFreq also does line-of-sight checks and applies some interesting math when signals graze the terrain at shallow angles. But that’s mostly just an exercise in ray tracing. Maybe we’ll chat about it some other time. ↩</code></pre></li><li><p></p><pre><code>Watch this if you’d like to ruminate on it more. ↩</code></pre></li><li><p></p><pre><code>…not that it stops superpowers from building them to talk to underwater submarines. Welcome to the sci-fi world of *extremely low frequency* comms. ↩</code></pre></li><li><p></p><pre><code>Well, impedance, electrical nerd for “resistance that can change over time or over frequency” ↩</code></pre></li><li><p></p><pre><code>If you’re wondering where the extra 4.1 kHz comes from, it was chosen in the late 1970s for CD audio to give filters a little extra headroom. ↩</code></pre></li><li><p></p><pre><code>Not so fun fact: The term “imaginary numbers” was coined by Descartes as a complaint about how useless he thought they were. Euler would prove him quite wrong in the next century, yet we still use Descartes’s insult to describe roots of -1. I was in my 30s before someone taught me how nice complex numbers are for representing rotations and frequencies, like we’re talking about today. ↩</code></pre></li></ol>","headings":[{"level":1,"text":"Simulating Airband AM Radios","id":"simulating-airband-am-radios"},{"level":2,"text":"Radio 101: path loss, decibels, SNR","id":"radio-101-path-loss-decibels-snr"},{"level":2,"text":"Amplitude modulation","id":"amplitude-modulation"},{"level":2,"text":"What’s in a radio?","id":"what-s-in-a-radio"},{"level":3,"text":"Filtering","id":"filtering"},{"level":3,"text":"Automatic gain control","id":"automatic-gain-control"},{"level":3,"text":"AM demodulation","id":"am-demodulation"},{"level":3,"text":"Squelch","id":"squelch"},{"level":2,"text":"Interference","id":"interference"},{"level":2,"text":"Again! But with computer!","id":"again-but-with-computer"},{"level":3,"text":"Filtering","id":"filtering-2"},{"level":3,"text":"IQ sampling","id":"iq-sampling"},{"level":3,"text":"A baseband AM simulation","id":"a-baseband-am-simulation"}]}}