Add audio-to-MIDI import via Basic Pitch (MP3, WAV, M4A, OGG, FLAC, AAC), fix piano remount on view change
This commit is contained in:
@@ -1,11 +1,26 @@
|
||||
# Optional audio-transcription dependencies (Basic Pitch).
|
||||
# Requires Python 3.11 or 3.12, tensorflow-macos doesn't yet support 3.13.
|
||||
#
|
||||
# To enable MP3 / audio-to-MIDI transcription:
|
||||
# brew install python@3.12
|
||||
# /opt/homebrew/bin/python3.12 -m venv .venv
|
||||
# Requires Python 3.11 on macOS. (basic-pitch's tensorflow-macos<2.15.1
|
||||
# constraint excludes 3.12+ - no compatible tensorflow-macos wheel exists.)
|
||||
# Linux is more flexible; 3.11 or 3.12 both work there.
|
||||
#
|
||||
# To enable MP3 / audio-to-MIDI transcription on macOS:
|
||||
# brew install python@3.11
|
||||
# /opt/homebrew/bin/python3.11 -m venv .venv
|
||||
# source .venv/bin/activate
|
||||
# pip install -r requirements-transcribe.txt
|
||||
#
|
||||
-r requirements.txt
|
||||
basic-pitch>=0.3.6
|
||||
|
||||
# setuptools < 81 is required because basic-pitch's dependency `resampy`
|
||||
# still imports `pkg_resources`, which setuptools 81 (released 2025) removed
|
||||
# after years of deprecation. Until upstream resampy migrates to
|
||||
# `importlib.metadata`, we pin to the last setuptools major that ships
|
||||
# pkg_resources (80.x).
|
||||
setuptools<81
|
||||
|
||||
# `[tf]` extra is REQUIRED since basic-pitch 0.4+ made the model backend opt-in.
|
||||
# Without it, basic-pitch installs but `predict()` fails (no TensorFlow to load
|
||||
# the ICASSP_2022_MODEL_PATH saved model). The `[onnx]` extra would be lighter
|
||||
# (~10 MB vs TF's ~500 MB) but our service uses the TF saved-model format.
|
||||
basic-pitch[tf]>=0.3.6
|
||||
|
||||
@@ -158,6 +158,27 @@ async def transcribe_mp3(file: UploadFile, background_tasks: BackgroundTasks):
|
||||
)
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
# Surface actionable runtime errors (e.g. missing basic-pitch) to the
|
||||
# client so the user knows what to install. Match by message substring
|
||||
# since exceptions may be wrapped on the way back.
|
||||
logger.exception("transcribe_mp3 failed")
|
||||
raise HTTPException(status_code=500, detail="Transcription failed. Please try again.")
|
||||
msg = str(e)
|
||||
# Only match the specific "not installed" sentinel - any other error
|
||||
# that happens to mention basic-pitch (e.g. file paths inside the
|
||||
# package, model-load failures) should NOT be wrongly reported as
|
||||
# "needs install".
|
||||
if "basic-pitch is not installed" in msg.lower():
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail=(
|
||||
"Audio-to-MIDI transcription needs Basic Pitch on the backend "
|
||||
"(not bundled by default).\n\n"
|
||||
"Quick install: with a Python 3.11 venv active on macOS (or 3.11/3.12 "
|
||||
"on Linux), run pip install -r backend/requirements-transcribe.txt. "
|
||||
"For Docker, see the README section 'Optional: Audio-to-MIDI via Basic Pitch'."
|
||||
),
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"Transcription failed: {msg or 'Unknown error'}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user