| |
| """Sortformer streaming diarization on AX650N: 16 kHz wav -> RTTM. |
| |
| python3 example.py meeting.wav out.rttm [--fast] |
| """ |
|
|
| import argparse |
| import sys |
| import time |
| from pathlib import Path |
|
|
| import numpy as np |
| import soundfile as sf |
|
|
| sys.path.insert(0, str(Path(__file__).resolve().parent)) |
|
|
| from sortformer_sdk import AxengineGraphPair, SortformerConfig, StreamingDiarizer |
|
|
| MODELS = Path(__file__).resolve().parents[1] / "models" |
|
|
|
|
| def main() -> None: |
| parser = argparse.ArgumentParser(description=__doc__) |
| parser.add_argument("wav") |
| parser.add_argument("rttm", nargs="?", default=None) |
| parser.add_argument("--fast", action="store_true", help="fifo40 encoder: RTF 0.064, DER +0.3~0.6pp") |
| parser.add_argument("--preencode", default=str(MODELS / "preencode.axmodel")) |
| parser.add_argument("--encoder", default=None) |
| parser.add_argument("--threads", type=int, default=8, help="reserved (numpy front-end is single-process)") |
| args = parser.parse_args() |
|
|
| encoder = args.encoder or str(MODELS / ("encoder_fifo40.axmodel" if args.fast else "encoder.axmodel")) |
| config = SortformerConfig( |
| fifo_len=40 if args.fast else 188, |
| spkcache_update_period=31 if args.fast else 144, |
| ) |
|
|
| waveform, sample_rate = sf.read(args.wav, dtype="float32", always_2d=True) |
| waveform = waveform.mean(axis=1) |
| if sample_rate != 16000: |
| raise SystemExit(f"expected 16 kHz wav, got {sample_rate}") |
|
|
| diarizer = StreamingDiarizer(AxengineGraphPair(args.preencode, encoder), config) |
| start = time.perf_counter() |
| preds = diarizer.process_wav(waveform, sample_rate) |
| elapsed = time.perf_counter() - start |
| duration = waveform.shape[0] / sample_rate |
|
|
| uri = Path(args.wav).stem |
| lines = diarizer.rttm_lines(preds, uri) |
| if args.rttm: |
| Path(args.rttm).write_text("\n".join(lines) + "\n") |
|
|
| print( |
| f"{uri}: {len(preds)} frames, {len(lines)} segments, " |
| f"{elapsed:.1f}s / {duration:.1f}s audio (RTF {elapsed / duration:.4f})" |
| ) |
| if args.rttm: |
| print(f"rttm -> {args.rttm}") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|