Find Duplicate Audio (Essentia HPCP)
Select a folder to scan. Uses Essentia.js HPCP (Harmonic Pitch Class Profile) chroma features to find duplicate and similar audio files — especially effective for cover versions and harmonic similarities.
Select a folder to scan. Uses Essentia.js HPCP (Harmonic Pitch Class Profile) chroma features to find duplicate and similar audio files — especially effective for cover versions and harmonic similarities.
A complete guide to finding duplicate and similar audio files using harmonic fingerprinting. Covers the Essentia.js HPCP algorithm, the Similarity Threshold slider, the custom player, and every button in the interface.
This tool finds duplicate and similar audio files by analysing the actual harmonic content of each file — not file names or metadata. It extracts a Harmonic Pitch Class Profile (HPCP) from each audio file using Essentia.js and compares profiles using cosine similarity, capturing the chord and pitch class structure that makes two recordings sound like the same song.
Unlike image duplicate finders, which compare visual pixels, HPCP audio comparison works in the harmonic domain. The tool can detect the same song re-encoded at a different bitrate, performed in a different key, or covered with different instrumentation — as long as the underlying chord progression and pitch content are similar.
Uses Essentia.js to extract 12-bin Harmonic Pitch Class Profiles — one per overlapping frame — capturing the chord and pitch class structure of the audio.
Compares HPCP vector sequences using cosine similarity. A score near 1.0 = nearly identical harmonic content. The slider controls how strict matching is.
Audio decoding and HPCP extraction continue even when you switch browser tabs — no pausing, unlike video scanning. Essentia.js WASM initialises once and is reused for every file.
Every card has a custom play/pause/seek/mute player. Playing one track automatically pauses all others.
The algorithm uses Essentia.js — a WebAssembly-compiled C++ music analysis library — to extract Harmonic Pitch Class Profiles (HPCP) from each audio file. Here is what happens step by step when you scan a file:
Before any file is processed, Sakarto initialises the Essentia.js WebAssembly module. This downloads the WASM binary from cdn.jsdelivr.net and compiles it in the browser. The process takes 1–3 seconds and happens once per session. The progress bar stays at 0% until initialisation completes.
Each file is decoded using AudioContext.decodeAudioData() at the native 44,100 Hz sample rate. Only the left channel is used. Files larger than 100 MB are skipped.
The decoded audio stream is divided into overlapping 4,096-sample frames with a 2,048-sample hop, giving ~50% overlap. At 44,100 Hz each frame is about 93 ms. More overlap means finer temporal resolution and more precise harmonic tracking than hash-based approaches.
extractor.hpcpExtractor() For each frame, Essentia's built-in hpcpExtractor(frame, sampleRate, false) method computes a 12-element Harmonic Pitch Class Profile — one bin per semitone of the chromatic scale (C, C#, D…B). This captures the relative harmonic energy at each pitch class, making the profile robust against loudness differences, bitrate changes, and minor re-encoding.
One 12-element vector is produced per frame. A 3-minute song at hop 2,048 produces roughly 3,800 vectors. The full sequence is stored in memory for comparison. This uses more RAM than a compact hash, but captures harmonic progression over time rather than just an average.
To compare two files, their HPCP sequences are aligned (using the shorter length) and the average cosine similarity is computed frame by frame. Cosine similarity of 1.0 means identical harmonic content; 0.0 means completely orthogonal. If the average meets or exceeds the threshold set by the slider, the files are grouped as duplicates. A duration pre-check rejects pairs where one file is shorter than 50% of the other.
The slider labeled Similarity Threshold (50–95) controls how strictly two HPCP profiles must match to be grouped as duplicates. It is the most important control on this page. Higher values are stricter — cosine similarity of 1.0 means a perfect match.
Only nearly identical files match. Use for exact duplicates, same file at different bitrates, or lossless vs. lossy exports of the same master. Very few false positives.
Catches cover versions, different-bitrate re-encodes of the same master, and transposed recordings. The default of 75 is a good starting point for music libraries. Some false positives are possible for songs with the same chord progression.
Groups files sharing broad harmonic character — same key, same genre, similar chord patterns. Useful for exploring harmonic relationships across a collection, but expect more false positives. Always review before deleting.
Every audio card has a built-in player. Here's how to use it:
| Control | What it does |
|---|---|
| ▶️ Play button | Starts playback. Automatically pauses any other playing track on the page. |
| ⏸️ Pause button | Pauses playback. Audio position is remembered. |
| Progress bar | Click anywhere on the bar to seek to that position. Drag left/right to scrub. |
| 🔊 / 🔇 Mute button | Mutes or unmutes this individual track. |
| 🔇 Audio (toolbar) | Mutes or unmutes all audio on the page at once. |
| Time display | Shows current position / total duration (e.g. 1:23 / 3:45). |
| ← / → arrow keys | When the progress bar is focused, seeks backward or forward 5 seconds. |
Click 📁 Select Folder to Scan. A native folder picker opens (Chrome / Edge). Or drag and drop a folder onto the page. All audio files inside the folder and its subfolders are collected. If this is your first scan, allow 1–3 seconds for the Essentia.js WASM module to initialise before the progress bar advances.
Supported formats: MP3, WAV, FLAC, OGG, M4A, AAC. Files over 100 MB are skipped. Non-audio files are silently ignored.
A progress bar shows how many files have been processed. Processing speed depends on file length and your CPU — expect roughly 2–5 seconds per track for typical music files, as HPCP extraction at 44,100 Hz is more CPU-intensive than hash-based methods. Duplicate groups appear live as they're found — you don't have to wait for the full scan to finish before reviewing results.
Click Stop at any time to halt the scan. Results found so far remain visible.
After scanning, use the Similarity Threshold slider to control matching sensitivity. Moving the slider re-groups all already-processed HPCP sequences instantly — no re-scanning is needed.
Results appear in numbered groups. Each group contains audio files that the algorithm considers similar. Use the built-in players to listen to each file before making decisions.
Ctrl+Click two or more cards, then click ⚖️ Compare in the toolbar. A modal opens showing each file with its own modal-size player, file metadata (duration, size, type, path), and a similarity percentage. For 3+ files, a full pairwise similarity matrix is shown.
Each file in the compare modal also has Copy Name, Move, and Delete buttons for quick actions without closing the modal.
Select files and use the toolbar. With Queue Mode on (recommended), files are staged for review first:
Queue Mode (enabled by default) stages files instead of acting immediately. Switch to the Move Queue or Delete Queue tab in the sidebar. Review the queued files, listen to them, remove any you change your mind about, then click Move All Files or Delete All Files to execute.
The default destination folder for Move is Audio-Duplicates, created inside the scanned folder. You can rename it in the queue input field.
| Button / Control | What it does |
|---|---|
| 🔄 New Search | Reload the page and start a fresh scan |
| 📋 Copy (N) | Copy selected filenames to clipboard. N = count. |
| 📂 Move (N) | Move selected files or stage them in Move Queue |
| 🗑️ Delete (N) | Delete selected files or stage in Delete Queue |
| ✕ Deselect All | Remove selection from all cards |
| ⚖️ Compare (N) | Open compare modal for Ctrl+clicked files. Needs 2+. |
| 🔇 Audio | Mute / unmute all audio players on the page |
| Queue Mode checkbox | Stage files for review before executing. Recommended on. |
| Similarity Threshold slider | Controls matching strictness (50–95, higher = stricter). Re-clusters instantly on release without re-scanning. |
| Click card | Select / deselect the file |
| Ctrl + Click card | Add / remove from compare list (purple border) |
| Click & drag (empty area) | Box-select multiple cards |
| Ctrl + drag | Add to existing selection with box |
| Right-click card | Context menu: Copy / Move / Delete / Compare |
| 🔍 hover icon on card | Open full-size preview with modal-size player |
| ▶️ on card player | Play audio. Pauses all other players on page. |
Always back up your audio library before deleting anything. Deleted files bypass the recycle bin and cannot be recovered.
Play both tracks using the built-in players before removing one. The algorithm is good but not perfect — always verify by ear for important files.
The default of 75 is well-calibrated for most music. Raise toward 85 if you see unrelated songs grouped. Lower toward 65 if expected duplicates are not appearing.
In the Compare modal, check file size and duration. A larger file is usually higher quality. Keep the FLAC or high-bitrate version; delete the compressed copy.
Use Move to an "Audio-Duplicates" folder rather than deleting outright. Review the moved files after a few days before permanently removing them.
For very large libraries, scan by genre or artist subfolder. This reduces false positives from tracks with similar instrumentation and keeps groups manageable.
If Essentia HPCP finds nothing, lower the threshold toward 60–65. For spoken word or sound effects, try Meyda MFCC. For exact copy detection without WASM, use Chromaprint.
Essentia.js loads from CDN and compiles in the browser before the first file can be processed. This 1–10 second pause is unavoidable and happens once per session. If it never completes, check that your network can reach cdn.jsdelivr.net — some firewalls and ad-blockers block CDN requests.
The File System Access API bypasses the OS recycle bin entirely. Deleted audio files are gone permanently. Queue Mode exists for exactly this reason — always review before executing.
HPCP stores a full array of 12-element vectors per file (one per frame). For very large libraries, RAM usage is significantly higher than compact hash methods. Scan in subfolders rather than entire drives.
You can't scan two separate folders in one session. Workaround: scan their common parent directory so both are included in the same scan.
The File System Access API is only available in Chrome 86+ and Edge 86+. Firefox and Safari can scan and display results but cannot move or delete files. Use "Download List" to export results in those browsers.
HPCP relies on harmonic pitch structure. Audio without clear pitch content (speech, noise, drums, ambient) produces near-random chroma vectors. Use Meyda MFCC for those file types.
cdn.jsdelivr.net. Try disabling your ad-blocker for this page, or open DevTools → Network and look for a blocked or failed request to Essentia. If the CDN is unreachable on your network, switch to Chromaprint — it's pure JavaScript, has no CDN dependency, and works completely offline.