PitchIn / audio_input.py
Hayeonbang's picture
Add PitchIn-Q free ZeroGPU demo with verified adapter
1d85885 verified
Raw History Blame Contribute Delete
2 kB
"""Bounded audio decoding for the interactive demo (not benchmark evaluation)."""
from pathlib import Path
import librosa
import numpy as np
import soundfile as sf
SAMPLE_RATE = 16000
MAX_SECONDS = 60
MAX_BYTES = 30 * 1024 * 1024
MAX_QUESTION_CHARS = 1000
DEFAULT_QUESTION = "How does my singing sound overall, and how can I improve?"
def prepare_input(audio_path, question):
question = (question or "").strip()
if not question:
raise ValueError("Please enter a question about your singing.")
if len(question) > MAX_QUESTION_CHARS:
raise ValueError(f"Please keep your question under {MAX_QUESTION_CHARS} characters.")
if not audio_path:
raise ValueError("Upload or record a singing clip first.")
path = Path(audio_path)
if not path.is_file() or path.stat().st_size > MAX_BYTES:
raise ValueError("Please upload an audio file smaller than 30 MB.")
try:
with sf.SoundFile(path) as handle:
sr = handle.samplerate
if not 8000 <= sr <= 192000 or not 1 <= handle.channels <= 2:
raise ValueError("Use mono or stereo audio with a sample rate of 8–192 kHz.")
if not sr <= handle.frames <= MAX_SECONDS * sr:
raise ValueError(f"Please use a clip between 1 and {MAX_SECONDS} seconds. Longer clips are not trimmed automatically.")
wave = handle.read(dtype="float32", always_2d=True).mean(axis=1)
except (sf.LibsndfileError, OSError) as exc:
raise ValueError("Could not read this audio. Try a WAV, FLAC, or MP3 file.") from exc
if not np.isfinite(wave).all():
raise ValueError("This audio contains invalid sample values. Please export it again.")
if np.max(np.abs(wave)) < 1e-5:
raise ValueError("This clip appears silent. Please upload a recording of singing.")
if sr != SAMPLE_RATE:
wave = librosa.resample(wave, orig_sr=sr, target_sr=SAMPLE_RATE)
return np.ascontiguousarray(wave, dtype=np.float32), question