⚡ MAJOR UPGRADE v2.0: Enterprise-ready music duplicate detection with advanced fuzzy matching, configuration profiles, comprehensive analytics, and high-performance caching (16+ files/second)
- Levenshtein Distance Algorithm for character-level similarity
- Smart Artist Normalisation (handles "The Beatles" = "Beatles", "AC/DC" = "ACDC")
- Featuring Artist Detection ("Madonna feat. Justin" = "Madonna")
- Acronym & Abbreviation Matching ("Pink Floyd" = "P. Floyd")
- Multiple Profiles: Default (95%), Conservative (98%), Aggressive (88%), HighQuality
- JSON-Based Storage with version control and profile switching
- Adaptive Thresholding based on metadata quality
- Command-line Profile Management (
-ListProfiles,-ShowConfig,-CreateConfig)
- Library Health Scoring (0-100 with recommendations)
- Interactive HTML Dashboards with charts and visual analytics
- Multi-Format Exports: CSV, JSON, HTML for different use cases
- Advanced Statistics: Format analysis, artist distribution, quality metrics
- 16+ files/second processing speed (10x improvement)
- Triple Caching System: Metadata, normalisation, similarity calculations
- Smart Memory Management with proper resource disposal
- Large Dataset Ready: 9,000+ files in ~20 minutes
# OLD v1.x Basic Usage:
.\duplicate_detection_with_threshold.ps1 "C:\Music" "None"
# NEW v2.0 Enhanced Usage:
.\duplicate_detection_with_threshold.ps1 -SourceFolder "C:\Music" -ConfigProfile "Default" -DuplicateAction "None"
# Performance Test (NEW):
.\duplicate_detection_with_threshold.ps1 -SourceFolder "C:\Music" -MaxFiles 50 -DuplicateAction "None"
# Profile Management (NEW):
.\duplicate_detection_with_threshold.ps1 -ListProfiles
.\duplicate_detection_with_threshold.ps1 -ShowConfig -ConfigProfile "Conservative"- 🧠 Advanced Fuzzy Matching: Levenshtein distance + intelligent artist normalisation
- ⚙️ Configuration Profiles: JSON-based Default/Conservative/Aggressive/HighQuality presets
- 📊 Analytics Dashboard: Library health scoring + interactive HTML reports
- ⚡ Performance Optimised: 16+ files/second with triple caching system
- 🔍 Multi-Factor Analysis: Combines metadata, filename, duration, and file size comparisons
- 📊 Borderline Match Logging: CSV export for manual review of uncertain matches
- 🛡️ Safety First: Preserves first occurrence, extensive validation, and backup recommendations
- 📈 Detailed Reporting: Comprehensive statistics and decision-support recommendations
- � Complete Enhanced Guide - Comprehensive v2.0 documentation
- 📋 This Guide - Quick reference and migration information
- 🔧 Configuration System - Profile management details
- 🧠 Fuzzy Matching - Algorithm implementation
- 🚀 Quick Start
- 📦 Installation
- ⚙️ Configuration
- 🎯 Usage Examples
- 📖 Complete Documentation
- 🤝 Contributing
- 📄 License
- Windows PowerShell 5.0+ or PowerShell Core 6.0+
- TagLib# library for metadata extraction
- Read/write access to your music folders
- Download the script:
duplicate_detection_with_threshold.ps1 - Install TagLib#: Place
TaglibSharp.dllin the script directory - Configure paths: Edit the configuration section in the script
- Run safely: Start with "None" action to analyse without modifying files
# Basic configuration
$SourceFolder = "C:\Music\YourCollection"
$DuplicateFolder = "C:\Music\Duplicates"
$DuplicateAction = "None" # Start with analysis only| Library Quality | Threshold | Adaptive | Borderline Range |
|---|---|---|---|
| Excellent (iTunes, tagged) | 0.95 |
✅ | 0.90-0.94 |
| Good (mixed sources) | 0.90 |
✅ | 0.85-0.89 |
| Poor (downloads, inconsistent) | 0.88 |
✅ | 0.82-0.87 |
- Download
duplicate_detection_with_threshold.ps1 - Download TagLib# from NuGet or GitHub
- Place
TaglibSharp.dllin the same directory as the script
Install-Package TagLibSharpThe script automatically searches for TagLib# in common locations:
- Script directory
- NuGet packages folder
- Program Files
- Common installation paths
📁 Basic Settings
#region --- Config ---
$SourceFolder = "E:\MUSIC\Reggae" # Source music folder
$DuplicateFolder = "C:\Duplicates\Reggae" # Where to move/copy duplicates
$Extensions = @("*.mp3", "*.m4a", "*.wma", "*.flac") # Supported formats
$SimilarityThreshold = 0.95 # Base detection threshold
$AdaptiveThresholding = $true # Enable smart adaptation
$DuplicateAction = "None" # "None", "Copy", "Move"
#endregion🔍 Borderline Match Logging
# Advanced: Borderline Match Analysis
$LogBorderlineMatches = $true # Enable CSV logging
$BorderlineMinThreshold = 0.85 # Minimum similarity to log
$BorderlineMaxThreshold = 0.92 # Maximum similarity to log
$BorderlineCsvPath = "$SourceFolder\BorderlineMatches_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"$SourceFolder = "C:\Music\TestFolder"
$DuplicateAction = "None" # Report only, no file operations
$SimilarityThreshold = 0.95 # Conservative threshold
$LogBorderlineMatches = $true # Enable detailed logging
.\duplicate_detection_with_threshold.ps1$SimilarityThreshold = 0.95
$DuplicateAction = "Copy" # Copy duplicates (safer than move)
$AdaptiveThresholding = $true # Auto-adjust per file
.\duplicate_detection_with_threshold.ps1$SimilarityThreshold = 0.88 # Lower threshold = more aggressive
$BorderlineMinThreshold = 0.85 # Log uncertain matches
$BorderlineMaxThreshold = 0.92
$DuplicateAction = "Move" # Permanent removal
.\duplicate_detection_with_threshold.ps1The Music Duplicate Detection script identifies and manages duplicate music files in large collections using a sophisticated multi-factor similarity scoring system. It's designed to handle real-world scenarios with mixed metadata quality, various file formats, and different encoding qualities.
- 🛡️ Safety First: Always preserve at least one copy of unique content
- 🧠 Intelligent Adaptation: Adjust behavior based on metadata availability
- 🎛️ User Control: Provide granular control over detection sensitivity
- 📊 Transparency: Detailed logging and reporting for informed decisions
- 🔄 Iterative Refinement: Support for threshold tuning through borderline match analysis
🔧 Technical Architecture
graph TD
A[Music Files] --> B[Metadata Extraction]
B --> C[Similarity Calculation]
C --> D{Adaptive Thresholding}
D --> E[Threshold Comparison]
E --> F{Above Threshold?}
F -->|Yes| G[Mark as Duplicate]
F -->|No| H{Borderline Range?}
H -->|Yes| I[Log for Review]
H -->|No| J[Mark as Unique]
G --> K[Action: None/Copy/Move]
I --> L[CSV Export]
J --> M[Keep Original]
The algorithm uses a weighted scoring system that combines multiple similarity factors:
📊 Total Similarity = (Metadata × 60%) + (Filename × 40%) + Duration Bonus + Size Bonus
🔍 Detailed Scoring Breakdown
1. 🎤 Metadata Similarity (60% weight)
- Artist Match: Binary (1.0 if exact match, 0.0 if different)
- Title Match: Binary (1.0 if exact match, 0.0 if different)
- Combined:
(Artist_Match + Title_Match) / 2 × 0.6
💡 Rationale: Metadata is the most reliable indicator of duplicate content when available and accurate.
2. 📝 Filename Similarity (40% weight)
- Algorithm: Character-by-character comparison from start
- Formula:
Matching_Characters / Min(Length1, Length2) × 0.4
💡 Rationale: Fallback for files with missing/incorrect metadata; handles systematic naming patterns.
3. ⏱️ Duration Bonus (5% bonus)
- Trigger: Durations within ±2 seconds
- Value: +0.05 to total score
💡 Rationale: Strong indicator of same content; accounts for encoding differences.
4. 💾 File Size Bonus (5% bonus)
- Trigger: Exact file size match
- Value: +0.05 to total score
💡 Rationale: Identical size often indicates same encoding/quality.
- Strategy: Keep the first encountered file, mark subsequent matches as duplicates
- Benefit: Preserves original organization and prevents loss of unique content
- Implementation: Array of processed files with metadata for comparison
| Score Range | Confidence Level | Description |
|---|---|---|
| 1.0 | Perfect Match | Identical metadata + filename + duration + size |
| 0.95-0.99 | High Confidence | Strong metadata match with supporting factors |
| 0.85-0.94 | Medium Confidence | Partial metadata match or strong filename similarity |
| 0.70-0.84 | Low Confidence | Weak similarities, likely false positive |
| <0.70 | No Match | Clearly different files |
⚖️ Weight Distribution Rationale
The 60/40 split between metadata and filename was chosen based on:
- 🎯 Metadata Reliability: When present and accurate, metadata is the most definitive indicator
- 📁 Filename Patterns: Many users have systematic naming conventions
- 🔄 Graceful Degradation: System remains functional with poor metadata
- 🎁 Bonus Factors: Duration and size provide additional confidence without overwhelming other factors
⚠️ Edge Cases Handled
Missing Metadata:
- Falls back to filename similarity
- Adaptive thresholding compensates by lowering requirements
Identical Metadata, Different Files:
- Duration and size bonuses help distinguish
- Filename differences can indicate different versions
Same Song, Different Quality:
- Metadata matches but size differs
- Duration typically matches (±2 seconds for encoding differences)
Automatically adjust similarity requirements based on available metadata quality per file.
💻 Implementation Logic
if ($AdaptiveThresholding) {
if (-not $Artist -or -not $Title) {
# Missing metadata - lower threshold (more lenient)
$CurrentThreshold = Max($BaseThreshold - 0.05, 0.85)
} else {
# Complete metadata - raise threshold (more strict)
$CurrentThreshold = Min($BaseThreshold + 0.02, 0.98)
}
}| Metadata Status | Adjustment | Rationale |
|---|---|---|
| ✅ Complete (Artist + Title) | +2% (max 98%) | Trust metadata for precise matching |
| ❌ Incomplete (Missing data) | -5% (min 85%) | Rely more on filename patterns |
- 🎯 Optimised Accuracy: Higher precision for well-tagged files
- 📈 Better Coverage: Improved detection for poorly-tagged files
- 🤖 Automatic Optimization: No manual threshold adjustment needed
- 📚 Mixed Library Support: Handles libraries with varying metadata quality
Capture potential duplicates that fall in the "gray area" between clear matches and clear non-matches for manual review.
⚙️ Configuration Strategy
Conservative Approach (Recommended for first-time users):
$SimilarityThreshold = 0.95
$BorderlineMinThreshold = 0.85
$BorderlineMaxThreshold = 0.92Aggressive Testing:
$SimilarityThreshold = 0.88
$BorderlineMinThreshold = 0.82
$BorderlineMaxThreshold = 0.87📊 CSV Output Structure
| Column | Purpose | Example |
|---|---|---|
Similarity_Score |
Overall weighted score | 0.8734 |
Threshold_Used |
Applied threshold (base or adaptive) | 0.90 |
Metadata_Score |
Artist + Title contribution | 0.60 |
Filename_Score |
Filename similarity contribution | 0.27 |
Duration_Bonus |
Duration match bonus | 0.05 |
Size_Bonus |
File size match bonus | 0.00 |
Recommendation |
Automated suggestion | REVIEW_NEEDED |
🔍 Analysis Workflow
- Export borderline matches to timestamped CSV
- Sort by similarity score (highest first)
- Review recommendations:
LIKELY_DUPLICATE: Close to threshold, probably duplicateLIKELY_UNIQUE: Close to minimum, probably uniqueREVIEW_NEEDED: Requires human judgment
- Identify patterns in false positives/negatives
- Adjust thresholds based on findings
- Re-run with refined settings
🌟 Excellent Metadata Quality (Professional collections, iTunes imports)
- Characteristics: Complete artist/title tags, consistent naming
- Recommended Threshold:
0.95-0.97 - Adaptive Thresholding: ✅ Enabled
- Borderline Range:
0.90-0.94
👍 Good Metadata Quality (Mixed sources, mostly complete)
- Characteristics: Some missing tags, generally well-organised
- Recommended Threshold:
0.90-0.93 - Adaptive Thresholding: ✅ Enabled
- Borderline Range:
0.85-0.89
⚠️ Poor Metadata Quality (Downloads, rips, inconsistent)
- Characteristics: Many missing tags, inconsistent naming
- Recommended Threshold:
0.85-0.88(first pass) - Adaptive Thresholding: ✅ Enabled
- Borderline Range:
0.80-0.87 - Strategy: Clean up obvious duplicates first, then raise threshold
📋 Phase-by-Phase Approach
Phase 1 - Conservative Cleanup:
- Set threshold to
0.95 - Enable borderline logging (
0.88-0.94) - Run with
"Copy"action - Review borderline matches
- Remove obvious duplicates manually
Phase 2 - Targeted Cleanup:
- Adjust threshold based on Phase 1 findings
- Narrow borderline range
- Run with
"Move"action - Monitor for false positives
Phase 3 - Fine-Tuning:
- Use lessons learned to optimize settings
- Run final cleanup with confidence
- Document optimal settings for future use
# Basic Configuration
$SourceFolder = "E:\MUSIC\Reggae"
$DuplicateFolder = "C:\OrganizedMusic\DUPLICATES\Reggae\L1"
$Extensions = @("*.mp3", "*.m4a", "*.wma", "*.flac")
# Core Detection Settings
$SimilarityThreshold = 0.95
$AdaptiveThresholding = $true
$DuplicateAction = "None" # Start with "None" for safety
# Borderline Match Logging
$LogBorderlineMatches = $true
$BorderlineMinThreshold = 0.85
$BorderlineMaxThreshold = 0.92"None" (Report Only):
- Purpose: Analysis and threshold tuning
- Safety: Highest (no files modified)
- Use Case: Initial runs, testing settings
"Copy" (Duplicate to Separate Folder):
- Purpose: Safe testing of duplicate detection
- Safety: High (originals preserved)
- Use Case: Validation before permanent removal
"Move" (Remove Duplicates):
- Purpose: Final cleanup
- Safety: Medium (duplicates permanently moved)
- Use Case: After thorough testing and validation
Source: E:\MUSIC\Genre\
├── Artist1\
├── Artist2\
└── ...
Duplicates: C:\OrganizedMusic\DUPLICATES\
├── Genre_L1\ # High-confidence duplicates
├── Genre_L2\ # Medium-confidence duplicates
└── Borderline\ # Manual review required
- Backup Your Library: Create complete backup before any operations
- Start Small: Test on a subset (single genre/artist) first
- Conservative Settings: Begin with high threshold (0.95+)
- Report-Only Mode: Use "None" action for initial analysis
- Review Results: Examine console output and borderline CSV
-
Analyse Borderline Matches:
- Open CSV in Excel/spreadsheet application
- Sort by similarity score
- Look for patterns in false positives/negatives
-
Adjust Thresholds:
- Lower threshold if missing obvious duplicates
- Raise threshold if catching too many false positives
- Adjust borderline range based on findings
-
Test with Copy Action:
- Run with "Copy" to validate settings
- Manually verify a sample of detected duplicates
- Check for any false positives
-
Production Run:
- Switch to "Move" action when confident
- Monitor results carefully
- Keep borderline logging enabled
- Backup created
- Test run on small subset completed
- Borderline matches reviewed
- Sample duplicates manually verified
- False positive rate acceptable
- Settings documented for future use
High False Positive Rate:
- Symptoms: Unique files being marked as duplicates
- Causes: Threshold too low, poor filename similarity algorithm
- Solutions: Increase threshold, enable adaptive thresholding, review metadata quality
Missing Obvious Duplicates:
- Symptoms: Clear duplicates not detected
- Causes: Threshold too high, missing metadata
- Solutions: Lower threshold, check metadata completeness, review filename patterns
Inconsistent Results:
- Symptoms: Similar files treated differently
- Causes: Adaptive thresholding edge cases, metadata inconsistencies
- Solutions: Review adaptive thresholding logic, standardise metadata
Performance Issues:
- Symptoms: Slow processing, high memory usage
- Causes: Large library size, inefficient comparison
- Solutions: Process in batches, optimize comparison algorithm
DLL Not Found:
- Ensure TaglibSharp.dll is in script directory
- Check NuGet packages folder
- Verify .NET Framework compatibility
Metadata Reading Errors:
- Corrupted files may cause exceptions
- Enable error handling for individual files
- Log problematic files for separate analysis
Large Libraries (>10,000 files):
- Consider processing by genre/artist
- Use SSD storage for temporary files
- Monitor memory usage during processing
Network Storage:
- Copy files locally before processing
- Use UNC paths carefully
- Consider network latency in time estimates
Enhanced Filename Similarity:
- Implement fuzzy string matching (Levenshtein distance)
- Handle common variations (featuring, feat., ft.)
- Normalise text (remove special characters, numbers)
Audio Fingerprinting:
- Integrate acoustic fingerprinting (e.g., AcoustID)
- Detect re-encoded versions of same content
- Handle different quality/format versions
Machine Learning Integration:
- Train models on manually verified duplicate pairs
- Learn from user feedback and corrections
- Improve similarity scoring weights automatically
GUI Application:
- Visual duplicate comparison
- Drag-and-drop folder selection
- Real-time preview of detected duplicates
Web Interface:
- Browser-based duplicate review
- Multi-user collaboration features
- Cloud storage integration
Batch Processing:
- Queue multiple folders for processing
- Scheduled automatic cleanup
- Progress resumption after interruption
Integration Capabilities:
- Music player integration (iTunes, Spotify, etc.)
- Cloud storage sync (Google Drive, OneDrive)
- Database export (SQLite, CSV, JSON)
Smart Organization:
- Automatic genre classification
- Quality-based duplicate selection
- Metadata enhancement suggestions
Memory Management:
- Current implementation stores all processed files in memory
- For libraries >50,000 files, consider database backend
- Implement streaming comparison for very large collections
Comparison Optimization:
- Early termination when threshold cannot be reached
- Indexing by metadata for faster lookups
- Parallel processing for multi-core systems
Modular Design:
- Separate similarity algorithms into distinct functions
- Configurable weight system for easy tuning
- Plugin architecture for additional similarity metrics
Error Handling:
- Graceful degradation for corrupted files
- Comprehensive logging for debugging
- Recovery mechanisms for interrupted processing
File Representation:
$ProcessedFile = @{
FullPath = $File.FullName
BaseName = $File.BaseName
Size = $FileSize
Artist = $Artist
Title = $Title
Duration = $Duration
Hash = $FileHash # Future: for exact duplicate detection
}Similarity Result:
$SimilarityResult = @{
Score = $CombinedSimilarity
MetadataScore = $MetaSim
FilenameScore = $NameSim
DurationBonus = $DurSim
SizeBonus = $SizeSim
Threshold = $CurrentThreshold
IsMatch = $IsMatch
}Unit Tests:
- Test individual similarity functions
- Validate threshold calculations
- Verify adaptive thresholding logic
Integration Tests:
- End-to-end duplicate detection
- CSV export functionality
- Error handling scenarios
Performance Tests:
- Benchmark with various library sizes
- Memory usage profiling
- Comparison algorithm efficiency
This duplicate detection system represents a sophisticated approach to managing music library duplicates with emphasis on safety, flexibility, and user control. The combination of multi-factor similarity scoring, adaptive thresholding, and borderline match logging provides a robust foundation for both automated and semi-automated duplicate management.
The key to success lies in understanding your library's characteristics and following the iterative refinement process to optimize settings for your specific needs. Always prioritize safety and thorough testing before permanent file operations.
- Start Conservative: Begin with high thresholds and report-only mode
- Use Borderline Logging: Invaluable for threshold tuning and quality assurance
- Enable Adaptive Thresholding: Automatically optimizes for metadata quality
- Iterate and Refine: Use data-driven approach to optimize settings
- Document Your Settings: Record optimal configurations for future use
For questions, issues, or suggestions regarding this duplicate detection system:
- Review this documentation thoroughly
- Check the borderline matches CSV for insights
- Test on small subsets before full library processing
- Maintain backups throughout the process
Remember: The goal is not perfect automation, but intelligent assistance in managing your music library efficiently and safely.
We welcome contributions! Here's how you can help:
- Use the GitHub Issues page
- Include your PowerShell version, library size, and error details
- Attach sample borderline matches CSV if relevant
- Check existing feature requests
- Describe the use case and expected behavior
- Consider backward compatibility
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Test thoroughly with various music libraries
- Update documentation as needed
- Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow PowerShell best practices
- Include error handling for edge cases
- Test with various metadata quality levels
- Update documentation for new features
- Maintain backward compatibility
This project is licensed under the MIT License - see the LICENSE file for details.
- TagLib#: For excellent metadata extraction capabilities
- PowerShell Community: For robust scripting platform
- Music Library Management Community: For inspiration and use cases
- 📚 Documentation: You're reading it! Check the sections above
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Direct Contact: Create an issue for private matters
Remember: The goal is not perfect automation, but intelligent assistance in managing your music library efficiently and safely.
Last Updated: October 31, 2025
Version: 2.0
Author: Benjamin Ohene-Adu