mroctopus / transcriber /transcribe.py
Ewan
Initial commit - Mr Octopus piano tutorial app
f0a176a
#!/usr/bin/env python3
"""Transcribe an audio file to MIDI using basic-pitch."""
import sys
from pathlib import Path
# Patch scipy.signal.gaussian (removed in scipy >=1.12, basic-pitch hasn't updated)
import scipy.signal
if not hasattr(scipy.signal, "gaussian"):
from scipy.signal.windows import gaussian
scipy.signal.gaussian = gaussian
from basic_pitch.inference import predict
import basic_pitch
_MODELS_DIR = Path(basic_pitch.__file__).parent / "saved_models" / "icassp_2022"
ONNX_MODEL_PATH = _MODELS_DIR / "nmp.onnx"
def transcribe(input_path: str, output_path: str | None = None):
input_file = Path(input_path)
if not input_file.exists():
print(f"Error: {input_file} not found")
sys.exit(1)
if output_path is None:
output_path = input_file.with_suffix(".mid")
else:
output_path = Path(output_path)
print(f"Transcribing {input_file}...")
model_output, midi_data, note_events = predict(
str(input_file),
ONNX_MODEL_PATH,
onset_threshold=0.33,
frame_threshold=0.20,
minimum_note_length=100.0,
)
midi_data.write(str(output_path))
print(f"MIDI written to {output_path}")
print(f"Found {len(note_events)} note events")
return output_path
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python transcribe.py <audio_file> [output.mid]")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
transcribe(input_file, output_file)