A conversation-driven refresher for engineers re-learning DSP
Digital frequency is the fractional travel a signal makes in-between sampling instants (i.e. phase advance or phase stride), expressed as a fraction of its wavelength (360°).
Picture this: While we were not looking — while the sampler was off doing something else — the analogue signal kept moving. When the ADC finally returns for its next sample, the signal has advanced by some slice of its own full cycle. That slice, that fraction, is the digital frequency.
Your running example: a 10 kHz tone sampled at 100 kHz. The signal's period is 100 µs; the sampler (ADC) pays our signal a visit every 10 µs to take sample. Each sample catches the sine one-tenth of a cycle further down as measured from the most recent sampling instant. The digital frequency is therefore 0.1 cycles per sample — or 36° per sample, or π/5 radians per sample. Same thing, different clothes. It takes the instrument or engineer 10% of the complete signal cycle to come back for another measurement - we don't care what the signal's frequency is, all we know is every 10% of it's cycle we are back measuring, again and again until our buffer is full
At Sonic Labs, wherever/whenever possible, we try build the intuition (the feel), before we compress all that in math. The formula, derived from intuition rather than decreed from above:
This ratio quantifies, or signals to us, how tightly we are tracking the signal's transitions.
| Sampler "laziness" | fs | Digital freq | What it looks like |
|---|---|---|---|
| Lazy (barely Nyquist) | 20 kHz | 0.5 | Hop 180° every sample — bounce between two points |
| Moderate (your plot) | 100 kHz | 0.1 | Hop 36° every sample — 10 hops to complete the circle |
| Greedy (oversampling) | 1 MHz | 0.01 | Hop 3.6° — barely any advance, stalking the signal |
Here is the central insight: the sine wave is merely the shadow of a dot traveling around a circle. The circle is the true signal. The sine wave is the side-view projection. The angle at any instant is the phase.
Your ADC is a strobe light flashing at f_s. Every flash freezes the dot at some angle. You write down the shadow height (the sample value) and wait for the next flash.
When we say "the signal advanced 36° since the last sample," we are literally saying "the dot hopped one-tenth of the way around the circle."
Any circle would do, but radius = 1 makes the shadow heights exactly your sine and cosine values. The complex exponential e^(jθ) is that dot on the unit circle. Euler simply gave us a way to carry both shadows in one number.
The FFT's fundamental question: "How many complete signal laps did the sampler acquire inside my N-sample window?"
From Section 1, the digital frequency of our 10 kHz signal sampled at 100 kHz is 0.1 cycles per sample — the signal advances one-tenth of a lap between each visit from the sampler. Across N samples, the total laps accumulated are:
If that product has a fractional part, the signal does not land cleanly on an FFT bin. The last sample catches the signal mid-lap, and when the record wraps around to repeat, there is a jump — a discontinuity the FFT reads as extra frequency content. That is leakage.
FFT bin k asks: "Does this signal contain exactly k complete cycles?"
For N = 1000: 100 complete cycles → bin 100 is hot → that is your 10 kHz tone.
For N = 1024: 102.4 cycles → not an integer → energy smears across bins 102 and 103. That is leakage — your signal did not fit neatly into the record.
Definition: the signal completes an integer number of full cycles inside your sample record.
where M = integer number of cycles and N = total samples.
This is not "fs is an integer multiple of fsignal." That is a special case, not the definition.
f0 = 10 kHz, fs = 100 kHz, N = 1000. M = 100 complete cycles → coherent → clean spike at bin 100. Here fs = 10 × f0, so the integer-multiple condition happens to hold.
f0 = 10 kHz, N = 1024 (a power of two, which FFTs love). For M = 100 cycles:
fs = 102.4 kHz — not an integer multiple of 10 kHz. Yet it is perfectly coherent: 100 complete cycles in 1024 samples. The FFT sees a seamless loop and gives a clean spike.
Here is the hardware engineer's gut punch, straight from the math above:
The denominator of your reduced digital-frequency fraction is your unique phase budget. That is how many distinct angles around the unit circle your sampler will ever see. Everything beyond that is a repeat — same phase, same information, wasted memory.
| Digital freq | Reduced fraction | Unique phases | Hardware reality |
|---|---|---|---|
| 0.1 | 1 / 10 | 10 | Buffer of 1000 = 990 wasted slots (same 10 angles, 100× over) |
| 0.5 | 1 / 2 | 2 | Buffer of 1024 = 1022 wasted slots |
| 0.25 | 1 / 4 | 4 | Buffer of 1024 = 1020 wasted slots |
| 0.09765625 | 25 / 256 | 256 | Buffer of 1024 = each phase repeated 4× |
You have three levers:
The FFT wants N samples to give you N/2 frequency bins. But the signal itself only needs denominator-many unique phases to be fully characterised. Everything else is the tax you pay for spectral resolution.
The FFT assumes your N-sample record repeats forever. If you cut off mid-cycle, the join between end and beginning is a sharp discontinuity. The FFT sees that as high-frequency junk — sidelobes.
Gentle fade-in and fade-out at the edges. It forces the signal to zero at the boundaries, so when the record repeats, there is no discontinuity.
Fading the edges throws away some information → broader peak (wider main lobe). But you kill the sharp discontinuity → sidelobes drop way down.
| Property | Hann | Rectangular (for contrast) |
|---|---|---|
| Coherent gain | ≈ 0.5 | 1.0 |
| First sidelobe | ≈ −31 dB | ≈ −13 dB |
| Main lobe width | ≈ 2× rectangular | Baseline |
The factor of 4 comes from: 2 for the energy split between positive and negative frequencies, and 2 for the Hann window's 0.5 coherent gain.
The theorem: fs > 2 × fmax (strictly greater than).
Why sample a 10 kHz signal at 100 kHz? You are oversampling (5×). The practical reasons:
| Reason | What it buys you |
|---|---|
| Anti-aliasing filter | A gentle, cheap analog filter instead of an impossible brick-wall |
| Processing gain / SNR | ~3 dB SNR improvement per octave of oversampling |
| Time resolution | 10 µs vs. 50 µs at bare Nyquist |
| Spectral leakage mitigation | More samples = finer bins = easier coherent sampling |
For a real-valued signal, sampling creates spectral replicas (images) at every integer multiple of fs. The negative frequency at −10 kHz gets shifted up by fs and lands at 90 kHz. Had you sampled at 20 kHz, that image would appear at 10 kHz — right on top of your signal.
Your plot shows 0 → fs (all N bins). This makes the conjugate symmetry obvious:
k = 10 kHz (positive frequency)N − k = 90 kHz (negative frequency, folded up)For a single-sided spectrum (0 → fs/2):
Your signal is Disc A, spinning at its own rate. The FFT's reference tone for bin k is Disc B, spinning at frequency k · fs/N. The DFT places them side by side and asks: "Do these two spin at the same rate?"
As you release the clutch, engine speed and wheel speed converge. The shudder you feel is beating — the periodic reinforcement and cancellation as the two speeds slip past each other. In spectral terms, this is leakage: two close frequencies creating an interference pattern. At lockup, the relative phase is frozen. The vibration stops. The DFT sees a single, clean spike.
The DFT is a bank of dot products. For each bin k:
x[n] is your signal disc, frozen at instant n.e−j2πkn/N is the reference disc, rotated to its position at instant n.x[n] · e−j2πkn/N is the projection at that instant: "how aligned are the radial lines right now?"The result is a complex number. Its magnitude tells you how much of frequency k is present. Its angle tells you the phase offset between signal and reference at lockup.
When the signal and reference frequencies are different, the product x[n] · e−j2πkn/N traces a closed polygon in the complex plane. The vector sum closes on itself → net zero. This is the orthogonality of the DFT basis: distinct frequencies are geometrically perpendicular in N-dimensional complex space.
When frequencies match, the product traces a straight line in the same direction → the vectors stack head-to-tail → maximum length.
The signal has a phase-advance rate. Each DFT bin sends a chaser through the same samples at a particular phase-advance rate. The bin that stays in step with the signal's phase advance accumulates coherently.
The radix-2 FFT begins by separating the DFT into contributions from the even-indexed and odd-indexed samples.
For the first half of the frequency bins, the frequency hunter combines the contribution from the even samples with the phase-rotated contribution from the odd samples.
The corresponding second-half frequency bin uses exactly the same even and odd intermediate results, but the odd contribution arrives with a 180° phase reversal.
The key identity is:
Since
therefore:
Remember the Hann window fades the edges to zero? In the gear picture, it's like gently engaging the clutch instead of dumping it. The abrupt edge discontinuity (rectangular window) is a violent clutch dump — high-frequency shudder everywhere. The Hann window smooths the engagement, letting the discs settle into lockup without the mechanical shock.