Last active
November 2, 2025 23:58
-
-
Save BenMcLean/be7cf1c25cb71647d0547ef2bc2f5950 to your computer and use it in GitHub Desktop.
Use mame-tools chdman to mass convert WAV/BIN/cue CD images to CHD format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Check if directory argument provided | |
| if [ $# -eq 0 ]; then | |
| echo "Usage: $0 <directory>" | |
| echo "Example: $0 /path/to/psx" | |
| exit 1 | |
| fi | |
| TARGET_DIR="$1" | |
| # Check if directory exists | |
| if [ ! -d "$TARGET_DIR" ]; then | |
| echo "Error: Directory does not exist: $TARGET_DIR" | |
| exit 1 | |
| fi | |
| # Function to format seconds into human-readable time | |
| format_time() { | |
| local seconds=$1 | |
| local hours=$((seconds / 3600)) | |
| local minutes=$(((seconds % 3600) / 60)) | |
| local secs=$((seconds % 60)) | |
| if [ $hours -gt 0 ]; then | |
| printf "%dh %dm %ds" $hours $minutes $secs | |
| elif [ $minutes -gt 0 ]; then | |
| printf "%dm %ds" $minutes $secs | |
| else | |
| printf "%ds" $secs | |
| fi | |
| } | |
| echo "Converting CD images to CHD in: $TARGET_DIR" | |
| echo "================================================" | |
| echo "" | |
| # Count total CUE files | |
| echo "Scanning for CUE files..." | |
| total_files=$(find "$TARGET_DIR" -type f -iname "*.cue" | wc -l) | |
| if [ $total_files -eq 0 ]; then | |
| echo "No CUE files found in $TARGET_DIR" | |
| exit 0 | |
| fi | |
| echo "Found $total_files CUE file(s) to convert" | |
| echo "" | |
| # Counter for statistics | |
| current=0 | |
| total_converted=0 | |
| total_failed=0 | |
| # Start time | |
| start_time=$(date +%s) | |
| # Find all .cue files | |
| find "$TARGET_DIR" -type f -iname "*.cue" | sort | while read -r cuefile; do | |
| ((current++)) | |
| dirname=$(dirname "$cuefile") | |
| basename=$(basename "$cuefile" .cue) | |
| chdfile="${dirname}/${basename}.chd" | |
| # Calculate progress percentage | |
| progress=$((current * 100 / total_files)) | |
| # Calculate time estimates | |
| current_time=$(date +%s) | |
| elapsed=$((current_time - start_time)) | |
| if [ $current -gt 1 ]; then | |
| avg_time_per_file=$((elapsed / (current - 1))) | |
| remaining_files=$((total_files - current + 1)) | |
| eta=$((avg_time_per_file * remaining_files)) | |
| eta_formatted=$(format_time $eta) | |
| elapsed_formatted=$(format_time $elapsed) | |
| else | |
| eta_formatted="calculating..." | |
| elapsed_formatted=$(format_time $elapsed) | |
| fi | |
| # Progress bar with standard ASCII characters | |
| bar_width=30 | |
| filled=$((progress * bar_width / 100)) | |
| empty=$((bar_width - filled)) | |
| bar=$(printf "%${filled}s" | tr ' ' '#') | |
| bar+=$(printf "%${empty}s" | tr ' ' '-') | |
| echo "[$bar] $progress% ($current/$total_files)" | |
| echo "Elapsed: $elapsed_formatted | ETA: $eta_formatted" | |
| echo "Converting: $basename" | |
| echo "---" | |
| # Convert to CHD (show all output) | |
| if chdman createcd -i "$cuefile" -o "$chdfile"; then | |
| echo "---" | |
| echo "✓ Successfully converted: $basename" | |
| # Parse cue file for referenced files and collect them | |
| cue_dir=$(dirname "$cuefile") | |
| files_to_delete=() | |
| # Add the cue file itself | |
| files_to_delete+=("$cuefile") | |
| # Parse cue file for referenced files (BIN, WAV, ISO, etc.) | |
| while IFS= read -r line; do | |
| # Match FILE lines with quoted or unquoted filenames | |
| if [[ $line =~ FILE[[:space:]]+\"([^\"]+)\" ]] || [[ $line =~ FILE[[:space:]]+([^[:space:]]+)[[:space:]] ]]; then | |
| referenced_file="${BASH_REMATCH[1]}" | |
| # Handle relative paths | |
| full_path="${cue_dir}/${referenced_file}" | |
| if [[ -f "$full_path" ]]; then | |
| files_to_delete+=("$full_path") | |
| fi | |
| fi | |
| done < "$cuefile" | |
| # Delete all referenced files | |
| for file in "${files_to_delete[@]}"; do | |
| echo " Removing: $(basename "$file")" | |
| rm -f "$file" | |
| done | |
| ((total_converted++)) | |
| echo "" | |
| else | |
| echo "---" | |
| echo "✗ Failed to convert: $basename" | |
| echo " Skipping deletion of source files" | |
| ((total_failed++)) | |
| echo "" | |
| fi | |
| done | |
| # Final statistics | |
| end_time=$(date +%s) | |
| total_time=$((end_time - start_time)) | |
| total_time_formatted=$(format_time $total_time) | |
| echo "================================================" | |
| echo "Conversion complete!" | |
| echo "Total time: $total_time_formatted" | |
| echo "" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This command will change the owner of all the CHDs:
sudo find /path/to/directory -type f -name "*.chd" -exec chown 1001:1001 {} +