Compare spectrum snapshots without diagnosing the hardware
Originally published on KeyboardTester.click: GPU vs PSU Coil Whine: How to Find the Source and Quiet It. This developer adaptation focuses on reading comparison data, not identifying a faulty computer component. Phot
Originally published on KeyboardTester.click: GPU vs PSU Coil Whine: How to Find the Source and Quiet It. This developer adaptation focuses on reading comparison data, not identifying a faulty computer component.
Photo: Elias GΓ‘mez / Pexels. The photo illustrates maintenance, not a new measurement.
An A/B spectrum screenshot invites a tempting shortcut: subtract two numbers and call the result a hardware diagnosis. The useful software boundary is narrower. A parser can validate the export, describe which relative quantities changed, and refuse to calculate a delta when the inputs do not support that comparison.
This exercise uses a versioned export containing saved A and B snapshots. You can run it entirely with the synthetic fixture below. It does not need microphone access, an account, a network connection or a particular GPU.
The input contract is smaller than the conclusion
The reference browser analyzer currently exports tool: "coil-whine-test", version: 1, readings, and microphone-processing metadata. Each saved reading has a boolean detected; a detected peak also carries frequency, level and prominence. An undetected snapshot uses null values for the absent peak fields. Additional metadata is retained in the original export, but this reader does not pretend it can establish microphone placement or gain from it.
The analyzer's search range is 1β18 kHz. Its 12 dB local-prominence gate is an implementation rule, not a universal equipment threshold. A 32,768-sample FFT at 48 kHz gives roughly 1.46 Hz bin spacing. As MDN documents, the FFT size specifies the analysis window. Bin spacing alone does not guarantee microphone accuracy or establish that nearby peaks share one physical source.
Three numbers deserve separate names:
- Frequency: where the selected narrow peak sits.
- Digital level: amplitude relative to digital full scale, in dBFS. This is not calibrated room dBA.
- Prominence: contrast against the local spectral background. A quieter background can increase prominence even when the selected tone's digital level falls.
The last case is why the program prints both deltas and never emits a field such as gpu_is_faulty.
A complete standard-library reader
Save this as compare_tones.py. It accepts only the known tool/version, checks detected snapshots for finite numeric values, and handles missing detections explicitly. Python booleans require special care: bool is a subclass of int, but false is not a valid audio level or schema version here.
"""Describe a Coil Whine Test v1 export without diagnosing hardware (MIT)."""
import argparse
import json
import math
import sys
def finite_number(value, name):
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise ValueError(name + " must be a number")
if not math.isfinite(value):
raise ValueError(name + " must be finite")
return value
def reading(value, name):
if not isinstance(value, dict) or type(value.get("detected")) is not bool:
raise ValueError(name + " needs a boolean detected field")
if not value["detected"]:
return {"detected": False}
result = {"detected": True}
for field in ("frequency", "level", "prominence"):
result[field] = finite_number(value.get(field), name + "." + field)
if not 1000 <= result["frequency"] <= 18000:
raise ValueError(name + " frequency is outside this tool's search range")
if result["level"] > 0 or result["prominence"] < 0:
raise ValueError(name + " has an invalid relative level")
return result
def summarize(payload, same_setup=False, tolerance_hz=20.0):
tolerance_hz = finite_number(tolerance_hz, "tolerance_hz")
if tolerance_hz < 0:
raise ValueError("tolerance_hz cannot be negative")
if not isinstance(payload, dict):
raise ValueError("export must be an object")
if payload.get("tool") != "coil-whine-test" or type(payload.get("version")) is not int or payload["version"] != 1:
raise ValueError("expected a coil-whine-test version 1 export")
snapshots = payload.get("readings")
if not isinstance(snapshots, dict):
raise ValueError("readings must be an object")
a, b = (reading(snapshots.get(key), key) for key in ("A", "B"))
result = {"A": a, "B": b, "hardware_source": "undetermined",
"same_setup_asserted_by_user": bool(same_setup),
"warning": "Relative digital data only; no calibrated SPL, defect or hearing-safety conclusion."}
if not same_setup:
result["status"] = "setup_not_confirmed"
elif not (a["detected"] and b["detected"]):
result["status"] = "missing_detected_pair"
elif abs(b["frequency"] - a["frequency"]) > tolerance_hz:
result["status"] = "different_peak_frequency"
else:
result.update(status="relative_pair", tolerance_hz=tolerance_hz,
frequency_delta_hz=b["frequency"] - a["frequency"],
level_delta_db=b["level"] - a["level"],
prominence_delta_db=b["prominence"] - a["prominence"])
result["warning"] += " Close frequencies do not prove the same physical tone."
return result
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("export_file")
parser.add_argument("--same-setup", action="store_true",
help="Assert that mic, distance, gain and workload comparison were controlled")
parser.add_argument("--tolerance-hz", type=float, default=20.0)
args = parser.parse_args()
try:
with open(args.export_file, encoding="utf-8") as source:
payload = json.load(source)
result = summarize(payload, args.same_setup, args.tolerance_hz)
except (OSError, ValueError) as error:
print("Cannot compare: " + str(error), file=sys.stderr)
return 2
print(json.dumps(result, indent=2, allow_nan=False))
return 0
if __name__ == "__main__":
sys.exit(main())
--same-setup is an assertion from the person conducting the comparison. It is not an automatic verification. Use it only after controlling the intended microphone, placement, distance, gain and workload comparison. The export cannot establish those conditions for you.
The default 20 Hz proximity tolerance is a conservative example setting for this reader, not a claim about auditory perception, resolution or hardware identity. Change it deliberately for your dataset. Even when two reported peaks fall within that tolerance, the output warns that they may not be the same physical tone.
Run a fixture that exposes the prominence trap
Create example.json:
{
"tool": "coil-whine-test",
"version": 1,
"readings": {
"A": {"detected": true, "frequency": 8000, "level": -55, "prominence": 20},
"B": {"detected": true, "frequency": 8002, "level": -59, "prominence": 22}
}
}
These are invented software fixtures, not recordings of a physical computer. Run:
python compare_tones.py example.json
python compare_tones.py example.json --same-setup
The first run returns setup_not_confirmed and no level delta. The second returns relative_pair, level_delta_db: -4 and prominence_delta_db: 2, while keeping hardware_source: "undetermined". The captured peak is lower in digital level yet more prominent against its neighboring bins. Collapsing those into one βnoise scoreβ would discard the distinction we wanted to preserve.
Change B's frequency to 9000: the status becomes different_peak_frequency, with no amplitude delta. Make A an undetected reading: the status becomes missing_detected_pair. Missing snapshots, the wrong tool/version, non-finite numbers, boolean numeric fields and invalid ranges produce a clear error instead of a plausible-looking result.
Fourteen deterministic tests were run for this exact implementation, including CLI success/error paths, tolerance boundaries, absent detections, validation and input immutability. They validate the reader's software behavior. They do not validate a microphone, GPU, PSU, physical repair or hearing-safety claim.
Input preflight belongs before the acoustic comparison
With real captures, first check which input reaches the browser. The SoundTesters microphone test provides a live input display and records a local sample for up to 30 seconds when started; listening requires an explicit playback choice. That is a useful way to discover a mistaken webcam-mic selection before interpreting an acoustic export. It is not a calibration or a coil-whine source detector.
Finish that input check, stop playback and live monitoring, and close the mic test before collecting acoustic snapshots. Speaker playback can contaminate a microphone measurement. Keep the acoustic analyzer visible beside the workload: the reference implementation stops capture when its tab is hidden. Record context in a separate note and repeat the pair rather than trusting a single screenshot.
No numeric reader can distinguish GPU from PSU solely because the pitch follows frame rate; both respond to load. Use manufacturer guidance for equipment questions, and stop using equipment with burning smells, sparks, crackling, shutdowns or damaged connectors.
Disclosure and reuse
The complete Python example is offered under the MIT license. It was prepared by an AI agent for this authorized publication and tested with synthetic fixtures. KeyboardTester.click and SoundTesters are owned by the same publisher; links identify the referenced export and input-preflight workflows, not independent endorsements. No new physical component diagnosis or repair result is claimed. The original guide covers the broader comparison method and its limitations.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.