Sliding Through Signal Streams and Stone
When you’re watching RF signals cascade down a waterfall display—those hypnotic vertical streams of colour showing signal strength over time—you’re witnessing one of computing’s most elegant algorithms at work. Every few milliseconds, the software grabs a fresh sample of spectrum data, slides it into view at the top, and lets the older samples drift downward into digital history. It’s a sliding window, and it’s the same algorithmic heartbeat that’ll help you carve those signals into translucent stone.
In Elixir, we can model this beautifully with streams:
defmodule Waterfall do
def process(signal_stream, window_size) do
signal_stream
|> Stream.chunk_every(window_size, 1, :discard)
|> Stream.map(&calculate_power_density/1)
|> Stream.each(&render_line/1)
end
defp calculate_power_density(samples) do
samples |> Enum.map(&(&1 * &1)) |> Enum.sum()
end
defp render_line(power), do: IO.puts(power)
end
The beauty here is lazy evaluation—each window slides forward only when needed, perfect for real-time processing. Meanwhile, Bash gives us a different flavour of the same concept when we’re preparing our lithophone data:
sliding_average() {
local window=$1; shift
local values=("$@")
for ((i=0; i<=${#values[@]}-window; i++)); do
sum=0; for ((j=i; j<i+window; j++)); do
sum=$((sum + values[j]))
done
echo $((sum / window))
done
}
sliding_average 3 10 20 30 40
Both implementations capture the essence: maintain a fixed-size view that glides through infinite data. In the 1970s, when memory was precious and processors modest, this algorithm became the backbone of real-time systems. Every radar screen, every audio mixer, every early graphics buffer relied on this simple idea.
For lithophanes, we’re sliding through brightness values to smooth transitions between thick and thin regions. For RF waterfalls, we’re sliding through frequency bins to create those mesmerising cascades. Same algorithm, different domains—proof that the most powerful computing concepts transcend their original contexts.