|
|
| """
|
| Generate self-paired manifests for IndexTTS2 training.
|
| This is a fix for datasets with unique speaker IDs where standard pairing fails.
|
| It creates pairs where Prompt == Target.
|
| """
|
|
|
| import argparse
|
| import json
|
| from pathlib import Path
|
| from typing import List, Dict
|
|
|
| def parse_args():
|
| parser = argparse.ArgumentParser(description="Create self-paired manifests.")
|
| parser.add_argument("--input", type=Path, required=True, help="Input single-speaker manifest.")
|
| parser.add_argument("--output", type=Path, required=True, help="Output paired manifest.")
|
| return parser.parse_args()
|
|
|
| def main():
|
| args = parse_args()
|
|
|
| if not args.input.exists():
|
| raise FileNotFoundError(f"Input manifest not found: {args.input}")
|
|
|
| print(f"Processing {args.input} -> {args.output}")
|
|
|
| pairs = []
|
| with args.input.open("r", encoding="utf-8") as f:
|
| for line in f:
|
| if not line.strip():
|
| continue
|
| entry = json.loads(line)
|
|
|
|
|
|
|
|
|
|
|
|
|
| if "condition_path" not in entry or "emo_vec_path" not in entry:
|
| print(f"Skipping incomplete entry: {entry.get('id')}")
|
| continue
|
|
|
| pair = {
|
| "id": f"{entry['id']}__{entry['id']}",
|
| "speaker": entry.get("speaker", "unknown"),
|
|
|
|
|
| "prompt_id": entry['id'],
|
| "prompt_audio_path": entry.get("audio_path", ""),
|
| "prompt_condition_path": entry["condition_path"],
|
| "prompt_condition_len": int(entry.get("condition_len", 32)),
|
| "prompt_emo_vec_path": entry.get("emo_vec_path", ""),
|
| "prompt_duration": entry.get("duration"),
|
| "prompt_language": entry.get("language"),
|
|
|
|
|
| "target_id": entry['id'],
|
| "target_audio_path": entry.get("audio_path", ""),
|
| "target_text": entry.get("text", ""),
|
| "target_text_ids_path": entry["text_ids_path"],
|
| "target_text_len": int(entry["text_len"]),
|
| "target_codes_path": entry["codes_path"],
|
| "target_code_len": int(entry["code_len"]),
|
| "target_emo_vec_path": entry.get("emo_vec_path", ""),
|
| "target_language": entry.get("language"),
|
| }
|
| pairs.append(pair)
|
|
|
|
|
| args.output.parent.mkdir(parents=True, exist_ok=True)
|
| with args.output.open("w", encoding="utf-8") as f:
|
| for p in pairs:
|
| f.write(json.dumps(p, ensure_ascii=False) + "\n")
|
|
|
| print(f"Done. Wrote {len(pairs)} self-paired entries.")
|
|
|
| if __name__ == "__main__":
|
| main()
|
|
|