A Short Review of the LOFAR Algorithm for Underwater Acoustic Analysis
Kumpee Teeravech
Geoinformatics Program (GI)
Faculty of Computer Science and Information Technology (CSIT)
Rambhai Barni Rajabhat University (RBRU)
2026-08-18
Several years ago, I had a chance to work with underwater acoustic analysis and was introduced
to two classical techniques used in passive sonar processing:
DEMON and
LOFAR.
I later used both techniques for vessel-sound analysis and classification on STM32
microcontrollers (Teeravech, 2020).
In my
previous article about the DEMON technique,
I reviewed how DEMON extracts low-frequency amplitude modulation from broadband underwater
noise, especially periodic characteristics that may be associated with propeller rotation,
blade passage, and cavitation. This article covers its complementary technique,
LOFAR, which examines the low-frequency spectral content of the received acoustic
signal and is useful for observing persistent tonal components produced by vessel machinery.
Please note that all of the content in this article was automatically generated by AI.
The discussion is intentionally limited to basic theory, the processing algorithm, and small
Python examples.
Please note that all of the content in this article was automatically generated by AI.
What Is LOFAR?
In passive-sonar processing, LOFAR commonly refers to
Low-Frequency Analysis and Recording. The basic idea is straightforward: listen to
underwater sound with a passive sensor, analyze the low-frequency portion of the signal,
transform it into the frequency domain, and observe how the spectrum changes with time.
A vessel contains many rotating and reciprocating machines. Engines, generators, pumps,
gearboxes, shafts, and other mechanical components can generate tonal or approximately
periodic acoustic components. After propagation through water, some of these components may
still appear as relatively narrow spectral lines.
LOFAR analysis therefore focuses on the ordinary acoustic spectrum. This is an important
distinction from DEMON, which analyzes modulation in the envelope of broadband noise.
Basic Idea
Suppose a hydrophone receives a signal
\[
x(t) = s(t) + n(t)
\]
where:
- \(s(t)\) represents acoustic energy generated by the target vessel, and
- \(n(t)\) represents ambient noise and other interfering sources.
A simple model for a machinery-dominated vessel signal is
\[
s(t)
=
\sum_{k=1}^{K}
A_k \cos(2\pi f_k t + \phi_k),
\]
where each \(f_k\) represents a tonal component associated with a mechanical or propulsion
source.
LOFAR attempts to make these frequencies visible by calculating the spectrum repeatedly over
short time windows.
A simplified processing chain is:
\[
\text{Audio}
\rightarrow
\text{Low-pass filtering}
\rightarrow
\text{Windowing}
\rightarrow
\text{FFT}
\rightarrow
\text{LOFAR spectrum}.
\]
Repeating the process over time produces a two-dimensional display usually called a
LOFARgram or LOFAR waterfall.
1. Acquiring the Underwater Signal
The input is normally a time-domain acoustic signal obtained from a hydrophone:
\[
x[n] = x(nT_s),
\]
where
\[
T_s = \frac{1}{F_s}
\]
is the sampling interval and \(F_s\) is the sampling frequency.
In my previous vessel-sound experiment, audio from several sources was resampled to
\[
F_s = 8192\ \mathrm{Hz}.
\]
The choice was made to cover the frequency range used by both DEMON and LOFAR processing
while keeping computation practical for the target microcontroller (Teeravech, 2020).
2. Low-Pass Filtering
LOFAR generally concentrates on a limited low-frequency portion of the acoustic spectrum.
A low-pass filter can therefore be applied:
\[
x_{\mathrm{LPF}}(t)
=
\mathrm{LPF}\{x(t)\}.
\]
The filter suppresses frequency components outside the desired analysis band and can also
serve as part of an anti-aliasing stage if the signal is subsequently downsampled.
In my 2020 experiment, the LOFAR processing parameters reported a low-pass cutoff of
approximately
\[
f_{\mathrm{LPF,max}} = 2046\ \mathrm{Hz}.
\]
This was an experimental setting rather than a universal LOFAR frequency limit. The appropriate
range depends on the target, sensor, environment, sampling rate, and purpose of the analysis.
3. Dividing the Signal into Short Windows
A single FFT describes only one interval of the signal. To examine how the spectrum changes
over time, the audio is divided into short, usually overlapping, frames:
\[
x_m[n]
=
x[n + mR],
\]
where:
- \(m\) is the frame index, and
- \(R\) is the hop size between consecutive frames.
If the frame contains \(N\) samples, its duration is
\[
T_{\mathrm{frame}} = \frac{N}{F_s}.
\]
For example, with \(F_s=8192\ \mathrm{Hz}\) and \(N=1024\):
\[
T_{\mathrm{frame}}
=
\frac{1024}{8192}
=
0.125\ \mathrm{s}.
\]
4. Applying a Window Function
Before calculating the FFT, each frame is usually multiplied by a window such as a Hann
window:
\[
x_w[n] = x[n]w[n].
\]
For a Hann window,
\[
w[n]
=
\frac{1}{2}
\left(
1 -
\cos\left(
\frac{2\pi n}{N-1}
\right)
\right).
\]
Windowing reduces spectral leakage caused by analyzing a finite segment of a continuous
signal.
5. Calculating the FFT
Each windowed frame is transformed into the frequency domain using the discrete Fourier
transform:
\[
X[k]
=
\sum_{n=0}^{N-1}
x_w[n]
e^{-j2\pi kn/N}.
\]
In practice, the Fast Fourier Transform (FFT) is used to calculate the same result efficiently.
The magnitude spectrum can be written as
\[
L[k] = |X[k]|.
\]
A power representation may instead be calculated as
\[
P[k] = |X[k]|^2.
\]
It is also common to display spectral magnitude or power in decibels:
\[
L_{\mathrm{dB}}[k]
=
20\log_{10}\left(|X[k]|+\varepsilon\right),
\]
where \(\varepsilon\) is a small positive value used to avoid taking the logarithm of zero.
Frequency Resolution
The frequency spacing between FFT bins is approximately
\[
\Delta f = \frac{F_s}{N_{\mathrm{FFT}}}.
\]
For example, if
\[
F_s = 8192\ \mathrm{Hz}
\]
and
\[
N_{\mathrm{FFT}} = 1024,
\]
then
\[
\Delta f
=
\frac{8192}{1024}
=
8\ \mathrm{Hz}.
\]
This gives a useful intuition for the 8 Hz/pixel LOFAR spectrogram resolution reported in my
earlier experiment (Teeravech, 2020).
The original paper also lists implementation parameters for the embedded processing chain,
including \(N=1024\), a decimation value of 32, and \(N_{\mathrm{FFT}}=256\). Those values
describe that particular implementation. For the simplified educational examples in this
article, I use a direct 1024-point analysis at 8192 Hz because it makes the relationship between
sampling rate, FFT size, and the reported 8 Hz frequency spacing explicit.
From LOFAR Spectrum to LOFARgram
If the spectrum is calculated repeatedly,
\[
L_1(f),\ L_2(f),\ L_3(f),\ldots,L_M(f),
\]
the spectra can be stacked to form a time-frequency representation:
\[
L(t,f).
\]
This two-dimensional representation is the familiar
LOFARgram or LOFAR waterfall.
A typical display uses:
- horizontal axis: acoustic frequency,
- vertical axis: time, and
- brightness or color: spectral magnitude or power.
A stable tonal source appears as a persistent line at approximately the same frequency.
A changing machine speed can cause a line to move gradually in frequency, while transient
events may produce short or broadband structures.
What Can LOFAR Reveal?
LOFAR is useful because a vessel is not acoustically represented by only one frequency.
Its spectrum may contain:
- engine-related tones,
- generator tones,
- pump and auxiliary machinery components,
- gear-related components,
- shaft-related tones,
- harmonics and sidebands, and
- broadband hydrodynamic and cavitation noise.
The resulting spectral pattern can act as an acoustic signature. In my earlier work, LOFAR
was treated as a broader-band feature useful for describing vessel machinery characteristics,
while DEMON was used to emphasize narrower modulation characteristics related to shafts and
propeller blades (Teeravech, 2020).
LOFAR versus DEMON
The easiest way to remember the difference is to ask:
what spectrum are we analyzing?
For LOFAR:
\[
\boxed{
\text{LOFAR}
\approx
\text{spectrum of the acoustic signal}
}
\]
For DEMON:
\[
\boxed{
\text{DEMON}
\approx
\text{spectrum of the signal envelope}
}
\]
A simplified comparison is:
| Aspect |
LOFAR |
DEMON |
| Main input for FFT |
Filtered acoustic waveform |
Envelope of filtered broadband noise |
| Main interpretation |
Actual acoustic frequencies |
Modulation frequencies |
| Typical useful information |
Machinery tones and spectral lines |
Shaft/blade-related periodic modulation |
| Time-frequency display |
LOFARgram |
DEMON waterfall / DEMONgram |
A Simple LOFAR Algorithm
A minimal digital LOFAR processing sequence can be summarized as:
- Acquire audio samples from a hydrophone.
- Resample the signal if necessary.
- Apply a low-pass or band-limiting filter.
- Divide the signal into short overlapping frames.
- Remove the frame mean if appropriate.
- Multiply each frame by a window function.
- Calculate the FFT.
- Convert the magnitude or power to logarithmic scale.
- Keep the frequency range of interest.
- Stack consecutive spectra to produce a LOFARgram.
Dummy Python Implementation
The following example calculates a single LOFAR spectrum. It is intentionally simple and is
intended to demonstrate the processing concept rather than reproduce a complete operational
passive-sonar system.
import numpy as np
from scipy.signal import butter, sosfiltfilt
from scipy.fft import rfft, rfftfreq
def lofar_spectrum(signal, fs):
# ---------------------------------------------------------
# 1. Low-pass filter
# ---------------------------------------------------------
f_max = 2046.0
sos = butter(
4,
f_max,
btype="lowpass",
fs=fs,
output="sos"
)
filtered = sosfiltfilt(sos, signal)
# ---------------------------------------------------------
# 2. Select one analysis frame
# ---------------------------------------------------------
n_fft = 1024
frame = filtered[:n_fft]
# Remove DC
frame = frame - np.mean(frame)
# ---------------------------------------------------------
# 3. Apply Hann window
# ---------------------------------------------------------
frame = frame * np.hanning(len(frame))
# ---------------------------------------------------------
# 4. FFT
# ---------------------------------------------------------
spectrum = np.abs(rfft(frame, n=n_fft))
freq = rfftfreq(
n_fft,
d=1.0 / fs
)
# Convert to dB
spectrum_db = 20.0 * np.log10(
spectrum + 1e-12
)
return freq, spectrum_db
Simple Test Signal
A synthetic signal makes the concept easy to see. Suppose a vessel-like signal contains
several stable tonal components:
import numpy as np
fs = 8192
duration = 5.0
t = np.arange(
0,
duration,
1.0 / fs
)
signal = (
1.00 * np.sin(2 * np.pi * 120 * t)
+ 0.60 * np.sin(2 * np.pi * 360 * t)
+ 0.35 * np.sin(2 * np.pi * 720 * t)
)
# Add broadband noise
signal += 0.50 * np.random.randn(len(t))
Although the waveform may look noisy, the LOFAR spectrum should contain strong components
near
\[
120,\ 360,\ 720\ \mathrm{Hz}.
\]
These frequencies are the actual acoustic spectral components of this synthetic signal.
Plotting a Single LOFAR Spectrum
import matplotlib.pyplot as plt
freq, spectrum_db = lofar_spectrum(
signal,
fs
)
plt.plot(freq, spectrum_db)
plt.xlim(0, 2046)
plt.xlabel("Acoustic frequency (Hz)")
plt.ylabel("Magnitude (dB)")
plt.title("LOFAR Spectrum")
plt.grid()
plt.show()
Generating a Simple LOFARgram
The more useful representation is obtained by applying the FFT repeatedly to overlapping
frames. SciPy's STFT function provides a compact way to demonstrate this:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter
from scipy.signal import sosfiltfilt
from scipy.signal import stft
def lofargram(signal, fs):
# Low-pass filter
sos = butter(
4,
2046.0,
btype="lowpass",
fs=fs,
output="sos"
)
signal = sosfiltfilt(
sos,
signal
)
# STFT
f, t, Zxx = stft(
signal,
fs=fs,
window="hann",
nperseg=1024,
noverlap=512,
nfft=1024,
boundary=None
)
magnitude_db = (
20.0 *
np.log10(
np.abs(Zxx) + 1e-12
)
)
# Keep only the frequency range of interest
mask = f <= 2046.0
return (
f[mask],
t,
magnitude_db[mask, :]
)
f, t, lofar_db = lofargram(
signal,
fs
)
plt.pcolormesh(
t,
f,
lofar_db,
shading="auto"
)
plt.xlabel("Time (s)")
plt.ylabel("Frequency (Hz)")
plt.title("LOFARgram")
plt.ylim(0, 2046)
plt.show()
The resulting image is a conventional time-frequency waterfall. Persistent tones should
appear as approximately horizontal lines when time is on the horizontal axis and frequency
is on the vertical axis. If the axes are exchanged, as in some traditional waterfall
displays, the same features appear vertically.
Interpreting a LOFARgram
Consider a persistent line around 600 Hz. In a LOFAR display, this means that the received
signal contains acoustic energy close to 600 Hz over an extended period.
This interpretation is different from a 6 Hz line in a DEMON spectrum. The DEMON line means
that some broadband energy is being modulated at approximately 6 Hz; it does not
necessarily mean that the original acoustic waveform contains a strong 6 Hz tone.
In my previous microcontroller experiment, one example showed a prominent LOFAR component
around 600-650 Hz, while the associated DEMON representation showed a different set of
low-frequency modulation peaks. This illustrates why the two representations can provide
complementary information (Teeravech, 2020).
Practical Limitations
Real passive-sonar data are much more difficult than the synthetic examples. A LOFARgram may
contain energy from:
- multiple vessels,
- biological sources,
- waves and weather,
- hydrophone and flow noise,
- harbor and industrial activity,
- multipath propagation,
- electrical interference, and
- other machinery in the environment.
Spectral lines can also drift as a vessel changes speed. Two unrelated machines may generate
similar frequencies, and propagation can strengthen or suppress different parts of the
spectrum.
Therefore, the presence of a spectral line alone is normally not sufficient to identify a
vessel. LOFAR is better viewed as a feature-extraction and visualization method whose results
can be interpreted together with other acoustic features, contextual information, or
classification algorithms.
Final Note
The fundamental idea of LOFAR can be summarized as:
\[
\boxed{
\text{Filter the acoustic signal}
\rightarrow
\text{calculate its spectrum repeatedly}
\rightarrow
\text{observe spectral lines over time}
}
\]
DEMON asks how broadband noise is being amplitude-modulated. LOFAR asks what acoustic
frequencies are actually present and how stable they are over time.
In my earlier work, I combined both representations and used the resulting DEMON and LOFAR
spectrograms as two input channels to a small CNN. The model was then deployed on STM32
microcontrollers for real-time vessel-sound classification (Teeravech, 2020).
Although modern underwater-acoustic recognition increasingly uses machine learning and deep
learning directly, LOFAR remains valuable because the resulting spectral representation is
physically interpretable and provides a direct view of persistent tonal components in an
underwater acoustic signal.
References
Chen, J., Liu, J., Liu, C., Zhang, J., & Han, B. (2021).
Underwater target recognition based on multi-decision LOFAR spectrum enhancement:
A deep learning approach.
arXiv.
https://arxiv.org/abs/2104.12362
Moura, N. N., Filho, E. S., & Seixas, J. M. (2009).
Independent component analysis for passive sonar signal processing.
Nielsen, R. O. (1991).
Sonar signal processing.
Artech House.
Teeravech, K. (2020).
Classification of vessel sound using DEMON and LOFAR techniques on STM32 microcontroller.
In Proceedings of the Sixteenth National Conference on Computing and Information
Technology (NCCIT2020) (pp. 425-430).