← All repositories

sample-sorts-test-repo

10 commits · main

README.md

Music Sample Sorter & Renamer - Modular Edition (v8)

A professional-grade tool for organizing and normalizing music sample libraries. Now with a clean, modular architecture for easy maintenance and extension.

Features

  • Intelligent Metadata Extraction: Automatically extracts BPM, key, type, and descriptors from filenames
  • Flexible Organization: Organizes files into a clean directory structure by type
  • Smart Deduplication: CRC32-based duplicate detection with skip or quarantine modes
  • Safe Operations: Dry-run by default, with copy and hardlink options
  • Comprehensive Logging: CSV reports with full processing details
  • Configurable: JSON-based configuration for custom mappings
  • Modular Design: Clean separation of concerns for easy maintenance

Project Structure

music_sorter/
├── music_sorter.py       # Main application entry point
├── config.py             # Configuration constants and mappings
├── text_utils.py         # Text processing utilities
├── extractors.py         # Metadata extraction from filenames
├── file_ops.py           # File system operations
├── filename_builder.py   # Normalized filename construction
├── processor.py          # File processing orchestration
└── README.md             # This file

Module Overview

music_sorter.py - Main Application

The entry point that:

  • Parses command-line arguments
  • Coordinates the overall process
  • Generates reports and statistics
  • Handles user interaction

config.py - Configuration

Contains all constants and mappings:

  • File type classifications
  • Target directory structure
  • Machine token lists
  • Descriptor whitelists/blacklists
  • Pack-specific defaults

text_utils.py - Text Processing

Handles text manipulation:

  • Tokenization and splitting
  • Vendor name normalization
  • Descriptor filtering
  • Filename sanitization

extractors.py - Metadata Extraction

Extracts information from filenames:

  • BPM detection (with index avoidance)
  • Musical key extraction
  • Type inference
  • Index number identification

file_ops.py - File Operations

Manages file system interactions:

  • CRC32 hashing
  • Move/copy/hardlink operations
  • Collision detection and resolution
  • Directory management

filename_builder.py - Filename Construction

Builds normalized filenames:

  • Schema: Type_Descriptors_BPM_Key_Vendor_Index.ext
  • Validation and sanitization
  • BPM formatting utilities

processor.py - File Processing

Orchestrates the processing pipeline:

  • Coordinates metadata extraction
  • Builds target paths
  • Handles deduplication
  • Executes file operations

Installation

No installation required! Just ensure you have Python 3.7+ installed.

# Clone or download the music_sorter directory
cd music_sorter

# Make the main script executable (optional)
chmod +x music_sorter.py

Usage

Basic Usage (Dry Run)

Preview what would happen without making changes:

python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC"

Apply Changes (Move Files)

Actually move the files:

python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --write

Copy Instead of Move

Keep original files in place:

python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --write --copy

With Deduplication

Skip or quarantine duplicate files:

# Skip duplicates
python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --dedupe skip \
  --write

# Quarantine duplicates
python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --dedupe quarantine \
  --write

Verbose Output

See detailed processing info:

python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --verbose

Debug Mode

See detailed BPM extraction logic:

python music_sorter.py \
  --source-root "/path/to/sample/pack" \
  --target-root "/path/to/library/MUSIC" \
  --debug

Filename Schema

The tool normalizes filenames to this schema:

Type_Descriptors_BPM_Key_Vendor_Index.ext

Example:

kick_heavy_distorted_120bpm_c_tr808_01.wav

Components:

  • Type: kick (required)
  • Descriptors: heavy, distorted (optional)
  • BPM: 120bpm (optional)
  • Key: c (optional)
  • Vendor: tr808 (optional)
  • Index: 01 (optional)
  • Extension: .wav (required)

Directory Structure

Files are organized into a clean hierarchy:

MUSIC/
├── ONE-SHOTS/
│   ├── Drum_Hits/
│   │   ├── Kicks/
│   │   ├── Snares/
│   │   └── Hats-Closed/
│   ├── Bass/
│   ├── FX/
│   └── Stabs/
├── LOOPS/
│   ├── Drums/
│   ├── Bass/
│   └── Melodic/
├── INSTRUMENTS/
│   ├── Synths/
│   ├── Keys/
│   └── Strings/
└── UNSORTED/
    ├── _UnknownType/
    └── Duplicates/

Configuration

Custom Mappings

Create a JSON file to override default mappings:

{
  "TYPE_MAP": {
    "mytype": "kick",
    "custom": "snare"
  },
  "MACHINE_TOKENS": ["customdrum", "mysynth"],
  "DESCRIPTOR_WHITELIST": ["custom", "descriptor"],
  "PACK_DEFAULT_TYPE": {
    "mypack": "instrument_synth"
  }
}

Use it:

python music_sorter.py \
  --source-root "/path/to/pack" \
  --target-root "/path/to/library" \
  --config my_config.json

Command-Line Options

Required

  • --source-root: Source directory with audio files
  • --target-root: Target directory for organized library

Optional

  • --csv: CSV report path (default: sort_report.csv)
  • --include-ext: File extensions to process (default: wav,flac,aiff,aif,mp3)
  • --dedupe: Deduplication mode: off, skip, quarantine (default: off)
  • --crc-db: CRC database path (default: crc_cache.json)
  • --config: JSON config file for custom mappings
  • --write: Apply changes (default is dry-run)
  • --copy: Copy files instead of moving
  • --hardlink: Create hardlinks instead of copying/moving
  • --verbose: Print detailed operation info
  • --debug: Enable debug mode with extraction details

Examples

Example 1: Organize a drum pack

python music_sorter.py \
  --source-root "/Downloads/TR-808 Samples" \
  --target-root "/Music/Library/MUSIC" \
  --write --verbose

Example 2: Deduplicate a large library

python music_sorter.py \
  --source-root "/Music/Unorganized" \
  --target-root "/Music/Library/MUSIC" \
  --dedupe quarantine \
  --write

Example 3: Preview with debug info

python music_sorter.py \
  --source-root "/Downloads/Synth Pack" \
  --target-root "/Music/Library/MUSIC" \
  --debug --verbose

BPM Detection

The tool intelligently extracts BPM values while avoiding false positives:

Examples of Correct Detection

✅ 120bpm_drumloop.wav → BPM: 120
✅ drumloop_140_heavy.wav → BPM: 140
✅ kick_95bpm.wav → BPM: 95

Examples of Avoided False Positives

❌ 67_HallOatsCombo.wav → No BPM (67 is an index)
❌ 808_kick.wav → No BPM (808 is a machine name)
❌ sample_303.wav → No BPM (303 is a machine name)

Extending the Tool

The modular design makes it easy to extend:

Add a New File Type

Edit config.py:

TYPE_MAP["mytype"] = "custom_type"
TARGET_DIR_MAP["custom_type"] = "CUSTOM/Type"

Add Custom Processing Logic

Create a new module and import it in processor.py or music_sorter.py.

Modify Extraction Logic

Edit the relevant function in extractors.py (e.g., extract_bpm, extract_key).

Troubleshooting

Files going to UNSORTED

Check the filename for recognizable type tokens. Add custom mappings in a config file if needed.

BPM not detected

Enable debug mode to see the extraction logic:

python music_sorter.py --source-root ... --target-root ... --debug

Duplicates not detected

Ensure --dedupe is set to skip or quarantine, and check that the CRC database is being saved.

Performance

  • Scanning: ~10,000 files/second
  • Processing: ~1,000 files/second (without deduplication)
  • Deduplication: ~500 files/second (includes CRC calculation)

License

This tool is provided as-is for personal and commercial use.

Changelog

v8 (Modular Edition)

  • Complete refactor into modular architecture
  • Separated concerns across 7 focused modules
  • Improved documentation and code clarity
  • Same functionality, cleaner codebase

v7

  • Fixed BPM detection for leading index numbers
  • Added debug mode
  • Improved machine token recognition

v6

  • Improved BPM and key extraction
  • Enhanced type inference
  • Better descriptor normalization

Support

For issues or questions:

  1. Check the debug output with --debug --verbose
  2. Review the CSV report for processing details
  3. Examine the module documentation in source files

Commit history

Files

18 tracked files at main.

  • .gitignore
  • ARCHITECTURE.txt
  • config.py
  • example_config.json
  • extractors.py
  • file_ops.py
  • filename_builder.py
  • FIX_SUMMARY.md
  • INDEX.md
  • MIGRATION_GUIDE.md
  • music_sorter.py
  • processor.py
  • QUICKSTART.md
  • README.md
  • README_FIRST.txt
  • REFACTORING_SUMMARY.md
  • test_modules.py
  • text_utils.py