
While driving the other day through a mountain pass the radio kept alternating between two stations which broadcast on the same frequency. It would play one station, loud and clear and after a few seconds switch to the other station. To me that’s surprising, as I would have expected to listen to a mash of both stations rather than a clear signal, albeit toggling between two stations. How could the radio tell the two stations apart? The answer, fortunately, is simple thanks to the FM capture effect [FCE]… which has nothing to do with what this post is about.
Expensive receivers have multiple antennas and are capable of discerning between same-frequency transmissions – but how do they use those many antennas to pick out a clear signal? The search lead to Independent Component Analysis [ICA] which can reconstruct original signals from a mix of signals, provided there are multiple receivers who receive different mixes. The underlying intuition is that dispersed receivers observe different mixtures, which are linear combinations (thank you, physics!) of the original signals. The more observers there are, the better the reconstructed signals will be.
[2025.08.20] Let’s assume we have three source signals s1(t), s2(t) and s3(t) which are read by receivers r1, r2 and r3. Each receiver reads a combination of the three signals:
r1(t) = a1*s1(t-φ1) + b1*s2(t-θ1) + c1*s3(t-ω1)
r2(t) = a2*s1(t-φ2) + b2*s2(t-θ2) + c2*s3(t-ω2)
r3(t) = a3*s1(t-φ3) + b3*s2(t-θ3) + c1*s3(t-ω3)
where:
an, bn , cn are attenuation components between 0 and 1, where lower values mean that the reception for that signal is weak (eg. the source is far away from the receiver or there is an obstacle between them).
φn, θn , ωn are phase offsets (in time units) which correspond for the time it takes for a signal to reach each receiver.
ICA is given r1, r2, r3 and reconstructs s1, s2, s3.
I wrote a simple demo [GIT] based on the fantastic ICA Python implementation from scikit-learn [SCI]. The demo consists of two experiments. The first experiment mixes together a few simple, synthetic signals, one mix per receiver, feeds ICA with the mixes and plots the results.

The second experiment uses old radio recordings (cowbells, horse races and a radio interview). The audio clips were mixed together three times. Each time the amplitudes and phase offsets of each clip in the mix were varied which resulted in different compositions for each receiver.
Original sound clips: cowbells, horse races, interview
Mixed signals: receiver1, receiver2, receiver3
Reconstructed signals: cowbells, horse races, interview

The source material and the reconstructed audio can be listened to here: https://github.com/ggeorgovassilis/ICA/tree/main/audio
Parting thoughts
It’s frankly amazing that ICA exists and actually works, and fast. The experiment shows that the more complex synthetic signal (composite sine) was reconstructed nearly perfectly, the rather simple pulse was mutilated badly, but at least the base frequency and phase survived. The radio recordings were reconstructed rather well, too, considering the source material’s quality (still: thank you BBC and Library of Congress for making these recordings available!). However, silent passages in the source signal are mercilessly overwritten with whichever of the other signals screamed loudest at that time.
[2025.08.20] Wikipedia says about ICA:
The success of ICA separation of mixed signals relies on […] assumptions […]
- The values in each source signal have non-Gaussian distributions.
That is a fancy way of saying that in order for signals to be recoverable, they should look like something “meaningful”, which is in parts a heuristic criterium and introduces a degree of subjectivity.
Future experiments should cover:
- understand ICA parametrisation
- more signals in the mix
- include synthetic signals in the radio mix to simulate EM interference
- better source material
- explore ways to recover silent passages
- can ICA be cheated?
Resources
[ICA] Independent Component Analysis on Wikipedia
https://en.wikipedia.org/wiki/Independent_component_analysis
[FCE] Capture effect on Wikipedia
https://en.wikipedia.org/wiki/Capture_effect
[SCI] sci-kit learn
https://scikit-learn.org/stable/
[GIT] ICA demo on Github
https://github.com/ggeorgovassilis/ICA/