Lab 13: Correlation — Does My Signal Contain This Note?
Time: ~60 minutes | Prerequisites: Lab 12 | Hardware: Pico 2 (no microphone needed)
This is the one. Take your time.
Every remaining lab in this course stands on the idea in this file. The good news: it's
one multiplication and one addition. Really. If you understand this lab, the FFT stops
being magic and becomes bookkeeping. Time to transform!
What You'll Build
A frequency detector. Give it a signal and a candidate frequency, and it answers: is that frequency in here? You'll build it, watch it fail on a phase shift, and then fix it.
Learning Objectives
- Explain how multiply-and-sum detects a frequency
- Describe why non-matching frequencies cancel to zero
- Demonstrate that a sine-only detector is blind to a phase-shifted signal
- Combine sine and cosine correlations into a phase-independent magnitude
- Connect correlation to the dot product
Concepts Introduced
| ID | Concept |
|---|---|
| 320 | Correlation |
| 321 | Multiply And Sum |
| 322 | Dot Product |
| 323 | Test Frequency |
| 324 | Similarity Measure |
| 325 | Orthogonal Functions |
| 326 | In Phase Component |
| 327 | Quadrature Component |
| 328 | Phase Independence |
| 329 | Correlation Magnitude |
| 330 | Basis Function |
| 331 | Projection Onto Basis |
Background
The whole idea, in one sentence
Multiply your signal by a test wave, add up the results, and see whether the total is big.
That's it. Here it is in code:
1 2 3 | |
Why it works
Think about what happens sample by sample.
When the frequencies match, the two waves rise and fall together. Positive times positive gives positive. Negative times negative also gives positive. Every product pushes the total the same direction, so it grows large.
When they don't match, the waves drift in and out of step. Sometimes both are positive, sometimes one is negative. The products land above and below zero at random and cancel each other out.
A large total means "yes, that frequency is in here." Near zero means "no."
You already know this as the dot product
Multiply matching elements, add up the results — that's the dot product from vector
maths, the thing that measures how much two vectors point the same way. Here the
"vectors" have 256 dimensions and each one is a wave. Two waves of different
frequencies are orthogonal — mathematically perpendicular. Their dot product is
zero, which is exactly why non-matching frequencies vanish.
Procedure
Step 1 — Play the guessing game
Open 13-correlation.py and run it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
Part 1 hides a tone in a signal and tests ten candidates:
1 2 3 4 5 6 | |
One candidate towers over the rest. You just found a hidden frequency using nothing but multiplication and addition.
Step 2 — Look inside the sum
Part 2 samples products from across the whole window:
1 2 3 4 5 6 7 | |
Matching: everything pulls the same way. Not matching: the signs alternate and fight. That's cancellation, visible.
Step 3 — Watch it break
Part 3 takes the same 300 Hz tone, shifts it by a quarter cycle, and tests again:
1 | |
Zero. The tone is unquestionably there and our detector says it isn't.
The reason: a quarter-shifted sine is a cosine, and a sine is orthogonal to a cosine of the same frequency. Our detector is blind to it.
A broken detector is a good teacher
This failure is the reason the real Fourier transform uses complex numbers. Not because
mathematicians enjoy them — because you need two measurements to pin down a wave
whose starting point you don't know. Meet the problem first and the solution stops
looking arbitrary.
Step 4 — Fix it with two test waves
Test with a sine and a cosine, then combine them like the legs of a right triangle:
1 | |
1 2 3 4 5 6 | |
Look at that magnitude column. The sin and cos scores swing around wildly as the phase changes — but the magnitude is 0.5000 every single time, and 0.0000 for the wrong frequency.
You now have a detector that answers "is this frequency present?" regardless of when the wave happened to start.
Step 5 — Predict, then measure
Prediction: what magnitude would a 300 Hz tone at half amplitude produce?
Change the mystery signal's amplitude to 0.5 and check. Does the relationship match what you expected?
Expected Output
See the tables above. The two numbers that matter: 0.5000 for every phase of the right frequency, 0.0000 for the wrong one.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| All candidates score near zero | Test frequencies don't fit whole cycles | Use multiples of RATE/N |
| Correlation isn't exactly zero | Floating-point rounding | 1e-17 is zero |
| Magnitude varies with phase | Using only the sine | You need both sine and cosine |
| Every candidate scores high | Signal has many frequencies | Try a single pure tone first |
Challenges
- Two tones. Make the mystery signal
sine(300) + 0.5*sine(500). Do both show up? Are the magnitudes in the right ratio? - In-between frequencies. Test 275 Hz against a 300 Hz signal. You'll get something that isn't zero or the full value. That leakage is Lab 22's whole subject.
- Recover the phase. The sin and cos scores encode when the wave started.
math.atan2(sin_score, cos_score)gives it back. Check it against the phase you put in.
Check Your Understanding
- Describe correlation in one sentence, without equations.
- Why does correlating two different frequencies give approximately zero?
- Why is a sine-only detector blind to a cosine of the same frequency?
- How do the sine and cosine scores combine into a magnitude?
- What does it mean for two waves to be orthogonal?
You built a frequency detector from scratch
One multiply, one add, and a square root at the end. Next lab you'll run this at every
frequency at once — and discover you've written a DFT. Nobody's going to hand it to
you. You're going to build it.
Next: Lab 14: Sweeping All Frequencies | Previous: Lab 12