MetricsMonitor is an FMDX Webserver Monitor plugin for displaying RDS and RF information, volume, equalizers, spectrum analyzer, and oscilloscope for FM audio, FM baseband, and MPX signals.
It extends the FM-DX-Webserver with a suite of professional-grade signal analysis tools. It captures MPX audio from a sound card or USB audio device, performs real-time FFT analysis on the server, and streams the results to all connected browser clients via WebSocket.
The plugin replaces the standard signal panel with a configurable multi-module display. Six display modes are available; they can be freely ordered, filtered by login state, and switched interactively by the user without a page reload.
bin/ folder)
Make sure the correct PE5PVB firmware is installed. You can either use the software-based MPX switching ("MPXmode": "auto" or "on") or you can permanently activate the MPX output in the audio settings menu.
If the Headless TEF has a line-level audio output, the MPX output can be permanently enabled via a jumper on the board. It is recommended to output the signal to a 192kHz compatible sound card, which is then configured as "MPXInputCard": "plughw:CARD=Device" (Linux) or "Microphone (HD USB Audio Device)" (Windows). Normal mono/stereo sound output continues to be handled by the i2s USB sound interface.
Anyone wishing to perform stereo decoding using MPX Tool or similar should use the settings "MPXmode": "on" and "MPXStereoDecoder": "on". This will result in permanent MPX output and stereo signaling on the display.
MetricsMonitorPlugin.js + MetricsMonitor Folder) to ..fm-dx-webserver-main\plugins\.npm run webserver or node . on the node.js console, check the console information.metricsmonitor.json (located in the folder: ../fm-dx-webserver-main/plugins_configs).server/helpers.js to exempt 127.0.0.1 from the anti-spam filter. This is required for the internal WebSocket communication.
A server restart is required after this patch is applied.
metricsmonitor.json is detected by a file watcher. Client JS files are regenerated and redeployed automatically — no restart needed.
MetricsMonitor provides six numbered display modules (IDs 0–5). You control which modules appear
and in what order via MODULE_SEQUENCE in the config file. The user can cycle through them by
clicking the panel or pressing number keys.
5-Band Audio Meter (metricsmonitor-audiometer.js)
Stereo L/R VU meters using the Web Audio API (Float32 precision), an RF signal bar, and five isolated frequency-band meters centred at 64 Hz, 256 Hz, 1 kHz, 4 kHz, and 10 kHz. Corrects the treatment of signals with different phases. Peak hold with configurable decay. Logarithmic dB scale (+5 dB to −26 dB). Completely browser-driven — no MPX capture needed.
MPX Meters (metricsmonitor-meters.js)
Six segment bar meters: LEFT, RIGHT (stereo audio), RF (signal strength), PILOT (19 kHz deviation in kHz), MPX (total composite deviation in kHz), and RDS (57 kHz subcarrier deviation in kHz). Values are derived from the MPX capture binary. Each meter shows a numeric value. Peak hold with 2 s decay.
MPX Spectrum Analyzer (metricsmonitor-analyzer.js)
Canvas-based FFT spectrum and revised waveform display of the FM composite signal. Horizontal range depends on sample rate: 48 kHz → 0–24 kHz, 96 kHz → 0–48 kHz, 192 kHz → 0–76 kHz. Smoothed with configurable attack/decay envelopes. Supports horizontal and vertical zoom, pan, hover cursor with frequency/dB readout.
Signal Meter (metricsmonitor-signalmeter.js)
Combined panel: LEFT/RIGHT stereo audio bars, ACI and CCI meters (replacing the previous RF/Multipath bars, based on R100DX/SignalGuard), a large numeric signal readout with highest-seen tracking, and status icons (RDS, Stereo, TP, TA, ECC flag).
Signal Analyzer (metricsmonitor-signal-analyzer.js)
A Chart.js realtime line chart plotting signal strength over time. Includes a graphical Channel Condition display plotting Signal value, Multipath (MP), ACI, and CCI. Supports horizontal zoom (time window), vertical zoom (dB range), and drag-to-pan.
MPX Oscilloscope (metricsmonitor-scope.js)
Time-domain waveform viewer of the MPX composite signal (up to 1024 samples/frame). Includes a switchable waveform display. Phosphor afterglow with up to 23 persistent traces. Peak-hold amplitude band in the background. REF level lines indicate 100 % modulation reference. Computes a 60-second windowed MPX power value (dBr).
EnableAnalyzerAdminMode is true, they are only accessible to authenticated admin users. When false, all users can see them.
Click anywhere inside the signal panel (#level-meter-container) to advance to the next module
in the configured MODULE_SEQUENCE. A 150 ms fade transition is applied between modes.
You can quickly switch between modules using the numeric keys. Which numbers are active depends on the number of activated modules. The counting always starts with the first value.
| Key | Action |
|---|---|
| 1 | Switch to the 1st module in MODULE_SEQUENCE |
| 2 | Switch to the 2nd module |
| 3 … 9 | Switch to the Nth module (if it exists) |
Press the CTRL key to select different zoom options in MPX + Signal analysis modes.
| Action | Effect |
|---|---|
| Scroll wheel | Horizontal zoom in/out |
| Ctrl + Scroll | Vertical zoom in/out (dB / amplitude axis) |
| Left-click + Drag | Pan the view horizontally (and vertically when Y-zoomed) |
| Right-click | Reset all zoom to 1.0× |
| Ctrl + ↑ | Zoom in horizontally |
| Ctrl + ↓ | Zoom out horizontally |
| Ctrl + ← | Pan left (when zoomed in) |
| Ctrl + → | Pan right (when zoomed in) |
| Ctrl + Space | Reset zoom to 1.0× |
| Action | Effect |
|---|---|
| Scroll wheel | Horizontal zoom (time window: 1 s – 120 s) |
| Ctrl + Scroll | Vertical zoom (dB range) |
| Left-click + Drag | Pan dB range up/down (only when vertically zoomed) |
| Right-click | Reset all zoom |
| Ctrl + ← / → | Decrease / increase time window |
A button labelled MPX/Signal toggles a full-width canvas overlay above the tuner that displays one of the canvas modules defined in CANVAS_SEQUENCE (IDs 2, 4, 5). Each click cycles through them.
If EnableSpectrumOnLoad is true, the first canvas module starts automatically.
| Icon | Description |
|---|---|
| ECC flag | Country/ECC badge cloned from the page's .data-flag element. |
| Stereo/Mono icon | Reflects the current stereo lock state. Clicking it sends B1 (force mono) or B0 (release) to the server. When MPXStereoDecoder = "on" it toggles between B1/B2. |
| PTY label | Shows the current RDS Programme Type as human-readable text. |
| TP / TA icons | Traffic Programme and Traffic Announcement flags from RDS. |
| RDS icon | Green when RDS lock is active. Also changes the signal panel background colour. |
The following variables can be changed in the metricsmonitor.json config file. After making changes, a server restart is only necessary for selected settings; a browser reload may also be sufficient!
"sampleRate": 48000, // Supported sample rate of input audio card (48000 / 96000 / 192000)
"MPXmode": "off", // MPX behavior: "off" / "auto" (switching) / "on" (always output)
"MPXChannel": "auto", // Fixed channel for MPX signal ("left", "right", "auto")
"MPXStereoDecoder": "off", // Set to "on" if decoding stereo signal from MPX
"MPXInputCard": "", // Exclusive MPX input (e.g., "plughw:CARD=Device")
"MPXTiltCalibration": 0, // Adjust input slope from -1000 µs to 1000 µs
"VisualDelayMs": 250, // Client-side delay in ms to sync with audio playback
"MeterInputCalibration": 0, // Global input gain offset in dB for meters
"MeterPilotCalibration": 0, // Offset for Pilot deviation
"MeterMPXCalibration": 0, // Offset for MPX deviation
"MeterRDSCalibration": 0, // Offset for RDS deviation
"MeterPilotScale": 400, // Scale factor for Pilot deviation
"MeterMPXScale": 100, // Scale factor for MPX deviation
"MeterRDSScale": 750, // Scale factor for RDS deviation
"fftSize": 512, // Frequency sampling rate (higher = better resolution, more CPU)
"SpectrumInputCalibration": 0, // Input gain offset in dB for spectrum
"SpectrumAttackLevel": 3, // Response rate as signal increases
"SpectrumDecayLevel": 15, // Smoothing decay (higher = stronger smoothing)
"SpectrumSendInterval": 30, // MS between WebSocket spectrum frames
"SpectrumYOffset": -40, // Curve offset
"SpectrumYDynamics": 2, // Curve dynamic multiplier
"ScopeInputCalibration": 0, // Amplitude gain offset for oscilloscope
"StereoBoost": 2, // Gain factor for stereo L/R VU meter
"AudioMeterBoost": 1, // Gain factor for equalizer display
"MODULE_SEQUENCE": "1,2,5,0,3,4",// Click-cycle order of modules inside panel
"CANVAS_SEQUENCE": "2,5,4", // Cycle order for the canvas overlay
"MultipathMode": 0, // 1 = TEF Radio smooth, 0 = Raw MP Data
"LockVolumeSlider": true, // Lock main volume slider to prevent measurement distortion
"EnableSpectrumOnLoad": false, // Automatically open canvas overlay on load
"EnableAnalyzerAdminMode": false,// Restricts canvas modules to admin users only
"MeterColorSafe": "rgb(0, 255, 0)", // Safe range color
"MeterColorWarning": "rgb(255, 255, 0)", // Warning range color
"MeterColorDanger": "rgb(255, 0, 0)", // Danger range color
"PeakMode": "dynamic", // "fixed" or "dynamic"
"PeakColorFixed": "rgb(251, 174, 38)", // Custom color for peak if PeakMode is fixed
Proper calibration ensures that the meter readings match real broadcast standards.
Inject a 100 % modulation test tone (typically ±75 kHz deviation at 1 kHz) into your tuner.
Observe the MPX Total meter. If the Pilot, MPX, and RDS meters show no signal level, increase the MeterInputCalibration in increments of 5. If the meters are in the red zone, decrease the MeterInputCalibration in increments of 5.
MeterPilotScale: Adjust this up/down (100/50 steps) until you reach approximately 7 kHz (Standard is 9%).MeterMPXScale: Adjust this up/down (100/50 steps) until you reach approximately 75 kHz.MeterRDSScale: Adjust this up/down (100/50 steps) until you reach approximately 2.0 kHz.
Now you can use the calibration tool to calculate the exact scale values so that the calibration offset values (MeterPilotCalibration, etc.) remain at 0:
Launch Metrics Monitor Calibration Tool
If you prefer not to use the tool, you can adjust the calibration variables directly in the decimal range (0.x). Note: The calibration variables should only be used for direct fine-tuning, as otherwise they will distort the measurement result.
MeterPilotCalibration: -0.5MeterMPXCalibration: -0.2MeterRDSCalibration: -0.5
The spectrum curve baseline (noise floor) should sit near the bottom of the display.
Decrease Spectrum-Y-Offset (make more negative) to move the curve down if the noise floor is too high.
Typical working value: -40 to -60.
If the spectrum shows a rising slope toward high frequencies, set
MPXTiltCalibration to 50 (Europe) or 75 (Americas) to apply an inverse de-emphasis tilt. Set to 0 to disable.
Modules 0 (Audio Meter), 3 (Signal Meter), and parts of module 1 (MPX Meters) use the browser's Web Audio API to measure the live audio stream directly — entirely independent of the MPX capture.
The plugin connects to Stream.Fallback.Player.Amplification (the gain node of the FM-DX-Webserver audio player). A ChannelSplitterNode feeds separate AnalyserNodes for left and right channels. Amplitude is extracted as Float32 time-domain data, converted to dBFS, and mapped to the 0–100 % meter scale (+5 dBFS to −26 dBFS).
MetricsMonitor uses the existing FM-DX-Webserver WebSocket endpoint (/data_plugins) for real-time communication.
// Server → Client: MPX Packet
{
"type": "MPX",
"peak": 74.3, // MPX total deviation in kHz
"pilotKHz": 8.97, // Pilot tone deviation in kHz
"rdsKHz": 3.82, // RDS subcarrier deviation in kHz
"s": [ ... ], // Spectrum magnitudes array (float32)
"o": [ ... ] // Oscilloscope waveform samples array
}
Setting EnableAnalyzerAdminMode to true restricts canvas modules (IDs 2, 4, 5) to authenticated admin users only. Non-admin visitors will still see the non-canvas modules (0, 1, 3) normally.
metricsmonitor_server.js, set let ENABLE_EXTENDED_LOGGING = true; to enable detailed console output of MPX/RDS/SNR values.localStorage.setItem("mm_meters_debug", "1"); for throttled output, or "all" for all WebSocket messages. Use localStorage.removeItem("mm_meters_debug"); to disable.LockVolumeSlider) if strictly needed, but it affects metered values.48 kHz: Sufficient for Modules 0 and 3. Displays FM audio spectrum up to 19 kHz.96 kHz: Required for the pilot tone display (Module 1). Displays FM baseband up to 38 kHz.192 kHz: Required for the full MPX and RDS displays. Displays MPX spectrum up to 56 kHz. For both 96 and 192 kHz, the receiver must support MPX output."EnableAnalyzerAdminMode": true on slower connections or hardware.Many thanks to Bojcha for the ideas and the code!
MetricsMonitor is developed by Highpoint.
GitHub: https://github.com/Highpoint2000/MetricsMonitor
Special thanks for support, testing, and ideas:
Released under the MIT License.
FM-DX-Webserver is an open-source project for FM radio DXing over the internet.
If you have any questions, would like to report problems, or have suggestions for improvement, please feel free to contact me! You can reach me by email at highpoint2000@googlemail.com. I look forward to hearing from you!