import os import itertools import random from pathlib import Path BASE_NAME = "vox" def get_song_names(base_path): """Get all song names from the ground_truth folder.""" ground_truth_path = Path(base_path) / f"original_format_trimmed_{BASE_NAME}" if not ground_truth_path.exists(): raise FileNotFoundError(f"Ground truth folder not found: {ground_truth_path}") song_names = [] for item in ground_truth_path.iterdir(): if item.is_dir(): song_names.append(item.name) return sorted(song_names) def verify_vocals_exist(base_path, model_folders, song_names): """Verify that vocals.wav exists for all songs in all model folders.""" missing_files = [] for model in model_folders: model_path = Path(base_path) / model for song in song_names: vocals_path = model_path / song / f"{BASE_NAME}.wav" if not vocals_path.exists(): missing_files.append(str(vocals_path)) if missing_files: print("Warning: Missing vocals.wav files:") for file in missing_files: print(f" - {file}") print() return len(missing_files) == 0 def create_vocal_pairs( base_path, output_file=f"{BASE_NAME}_pairs.txt", random_seed=None ): """ Create all pairs of vocals.wav between different models with random ordering. Args: base_path: Path to the parent folder containing model folders output_file: Name of the output file to save pairs random_seed: Seed for random number generator (for reproducible results) """ if random_seed is not None: random.seed(random_seed) base_path = Path(base_path) # Define model folders model_folders = [ f"original_format_trimmed_{BASE_NAME}", f"lalal_format_trimmed_{BASE_NAME}", f"suno_format_trimmed_{BASE_NAME}", ] # Verify all model folders exist for model in model_folders: model_path = base_path / model if not model_path.exists(): raise FileNotFoundError(f"Model folder not found: {model_path}") print(f"Base path: {base_path}") print(f"Model folders: {model_folders}") # Get song names from ground_truth folder song_names = get_song_names(base_path) print( f"Found {len(song_names)} songs: {song_names[:5]}{'...' if len(song_names) > 5 else ''}" ) # Verify all vocals.wav files exist all_files_exist = verify_vocals_exist(base_path, model_folders, song_names) if not all_files_exist: response = input("Some vocals.wav files are missing. Continue anyway? (y/n): ") if response.lower() != "y": return # Generate all pairs between different models pairs = [] for song in song_names: # Create all combinations of models (pairs) model_combinations = list(itertools.combinations(model_folders, 2)) for model1, model2 in model_combinations: path1 = base_path / model1 / song / f"{BASE_NAME}.wav" path2 = base_path / model2 / song / f"{BASE_NAME}.wav" # Skip if either file doesn't exist if not (path1.exists() and path2.exists()): continue # Randomly decide the order of the pair if random.choice([True, False]): pairs.append((str(path1), str(path2))) else: pairs.append((str(path2), str(path1))) # Shuffle all pairs random.shuffle(pairs) # Write pairs to file output_path = Path(output_file) with open(output_path, "w") as f: # Write CSV header f.write( "song_name,source_a,source_b,source_a_fp,source_b_fp,mixture_path,instrument\n" ) for file1, file2 in pairs: # Extract song name and source model from paths path1 = Path(file1) path2 = Path(file2) song_name = path1.parent.name # Should be same for both source_a = path1.parent.parent.name # Model folder name source_b = path2.parent.parent.name # Model folder name # Create path to ground truth mixture.wav mixture_path = ( base_path / f"original_format_trimmed_{BASE_NAME}" / song_name / f"mixture_{BASE_NAME}_trimmed.wav" ) instrumental = "instrumental" if BASE_NAME == "vox" else BASE_NAME f.write( f"{song_name},{source_a},{source_b},{file1.replace('vox.wav', 'instrumental.wav')},{file2.replace('vox.wav', 'instrumental.wav')},{mixture_path},{instrumental}\n" ) print(f"\nGenerated {len(pairs)} pairs") print(f"Results saved to: {output_path.absolute()}") return pairs def main(): # Example usage base_path = ( "/app2/suno/data/sara/musdb/audio_comparison2/" # Update this path as needed ) # You can set a seed for reproducible results pairs = create_vocal_pairs( base_path=base_path, output_file=os.path.join(base_path, f"{BASE_NAME}_pairs_trimmed.txt"), random_seed=42, # Remove or set to None for truly random results ) if pairs: print("\nFirst 3 pairs as example:") for i, (file1, file2) in enumerate(pairs[:3], 1): print( f" Pair {i}: {Path(file1).parent.parent.name} vs {Path(file2).parent.parent.name}" ) print(f" Song: {Path(file1).parent.name}") if __name__ == "__main__": main()