tunebase / services /midi_converter.py
anggars's picture
Initial HF Space deployment
6319e2f
from basic_pitch.inference import predict_and_save
from basic_pitch import ICASSP_2022_MODEL_PATH
import os
class MidiConverter:
def __init__(self):
print("Initializing Basic Pitch for MIDI conversion...")
self.output_dir = "midi_output"
def convert(self, audio_path: str, output_path: str):
"""
Convert audio file to MIDI using Basic Pitch.
"""
try:
# basic-pitch handles loading internally
# It saves multiple files (mid, csv, npz), we only care about mid
# output_path should be a directory or file?
# predict_and_save takes output_directory
output_dir = os.path.dirname(output_path)
file_name_no_ext = os.path.splitext(os.path.basename(output_path))[0]
print(f"Converting {audio_path} to MIDI...")
# Tuned parameters for better accuracy
predict_and_save(
[audio_path],
output_dir,
True,
False,
False,
False,
ICASSP_2022_MODEL_PATH,
onset_threshold=0.6, # Higher threshold to reduce noise
frame_threshold=0.4,
minimum_note_length=100.0, # ms
minimum_frequency=None,
maximum_frequency=None
)
# Basic Pitch saves as <original_name>_basic_pitch.mid
# We need to rename it to expected output_path if needed
original_basename = os.path.splitext(os.path.basename(audio_path))[0]
generated_midi = os.path.join(output_dir, f"{original_basename}_basic_pitch.mid")
if os.path.exists(generated_midi):
if os.path.exists(output_path):
os.remove(output_path)
os.rename(generated_midi, output_path)
print(f"MIDI saved to {output_path}")
return output_path
else:
print("Warning: Expected MIDI file not found.")
return None
except Exception as e:
print(f"Error converting to MIDI: {e}")
import traceback
traceback.print_exc()
return None