Spaces:
Running
Running
Download frontend_app.py from teamup-tech/DDSP: direct link, hf CLI and curl.
- Browser
- Download file 5.23 kB
-
https://huggingface.co/spaces/teamup-tech/DDSP/resolve/main/frontend_app.py
- Command line
-
hf download hf://spaces/teamup-tech/DDSP/frontend_app.py
-
curl -L -o frontend_app.py https://huggingface.co/spaces/teamup-tech/DDSP/resolve/main/frontend_app.py
5.23 kB
| from __future__ import annotations | |
| import json | |
| import os | |
| import subprocess | |
| import gradio as gr | |
| from pyharp import * | |
| _BACKEND_PYTHON = os.environ.get("BACKEND_PYTHON", "/opt/backend/bin/python") | |
| _BACKEND_SCRIPT = os.environ.get("BACKEND_SCRIPT", "/app/backend_worker.py") | |
| _BACKEND_TIMEOUT = float(os.environ.get("BACKEND_TIMEOUT", "900")) | |
| def _call_backend(payload): | |
| # One-shot subprocess into the isolated backend venv. The worker prints | |
| # exactly one JSON object as its final stdout line; all model/library | |
| # chatter is redirected to stderr (captured in the Space logs). | |
| completed = subprocess.run( | |
| [_BACKEND_PYTHON, _BACKEND_SCRIPT], | |
| input=json.dumps(payload), | |
| capture_output=True, | |
| text=True, | |
| timeout=_BACKEND_TIMEOUT, | |
| ) | |
| _lines = [ln for ln in completed.stdout.splitlines() if ln.strip()] | |
| try: | |
| response = json.loads(_lines[-1]) if _lines else {} | |
| except json.JSONDecodeError as exc: | |
| raise gr.Error( | |
| "The backend returned no valid result. Last stderr: " | |
| + (completed.stderr[-1500:] or "(empty)") | |
| ) from exc | |
| if not response.get("ok"): | |
| raise gr.Error( | |
| response.get("error") or completed.stderr[-1500:] or "Backend worker failed" | |
| ) | |
| return response.get("outputs") or {} | |
| model_card = ModelCard( | |
| name="DDSP", | |
| description=( | |
| "Differentiable DSP timbre transfer: recast your audio in the timbre of " | |
| "a pretrained instrument (Violin, Flute, Trumpet, ...). Runs the " | |
| "original, unmodified DDSP stack in an isolated Python 3.9 backend. " | |
| "The model is fixed-rate and mono, so the result is resampled back to " | |
| "the input's rate and copied across its channels: the output has the " | |
| "format it came in with, but no stereo image. " | |
| "Repository: https://github.com/magenta/ddsp Paper: " | |
| "https://arxiv.org/abs/2001.04643" | |
| ), | |
| author="Jesse Engel, Lamtharn Hantrakul, Chenjie Gu, Adam Roberts", | |
| tags=[Subcategory.TIMBRE_TRANSFER], | |
| ) | |
| def process_fn(audio, model_name, threshold, adjust, quiet, autotune, pitch_shift, loudness_shift): | |
| _inputs = dict(zip(["audio", "model_name", "threshold", "adjust", "quiet", "autotune", "pitch_shift", "loudness_shift"], [audio, model_name, threshold, adjust, quiet, autotune, pitch_shift, loudness_shift])) | |
| _outputs = _call_backend({"inputs": _inputs}) | |
| _out_out_audio = _outputs.get("out_audio") | |
| if not _out_out_audio: | |
| raise gr.Error("The backend produced no 'out_audio' output. Check the Space logs (the backend worker's stderr is captured there).") | |
| return _out_out_audio | |
| if __name__ == "__main__": | |
| with gr.Blocks() as demo: | |
| input_components = [ | |
| gr.Audio(type="filepath", label="Input audio").harp_required(True).set_info(( | |
| "A monophonic recording to recast. One voice or one instrument line " | |
| "at a time works; the model follows a single pitch, so chords " | |
| "confuse it." | |
| )), | |
| gr.Dropdown(choices=["Violin", "Flute", "Flute2", "Trumpet", "Tenor_Saxophone"], value="Violin", label="Instrument", | |
| info="The pretrained timbre to recast the input in."), | |
| gr.Slider(minimum=0.0, maximum=2.0, step=0.01, value=1.0, label="Note-detection threshold", | |
| info="Raise this if room noise or breath is being heard as notes."), | |
| gr.Checkbox(value=True, label="Auto-adjust to model range", | |
| info=( | |
| "Shifts the input into the pitch range the chosen instrument was " | |
| "trained on, which usually helps when the source sits much higher " | |
| "or lower." | |
| )), | |
| gr.Slider(minimum=0.0, maximum=60.0, step=1.0, value=20.0, label="Quiet parts (dB)", | |
| info=( | |
| "Raise this to silence quiet passages, lower it to let them " | |
| "through." | |
| )), | |
| gr.Slider(minimum=0.0, maximum=1.0, step=0.1, value=0.0, label="Autotune amount", | |
| info=( | |
| "Pulls detected pitches toward the nearest semitone. Zero keeps the " | |
| "original intonation, including any slides and vibrato." | |
| )), | |
| gr.Slider(minimum=-2.0, maximum=2.0, step=1.0, value=0.0, label="Pitch shift (octaves)", | |
| info="Transposes the input before synthesis."), | |
| gr.Slider(minimum=-20.0, maximum=20.0, step=1.0, value=0.0, label="Loudness shift (dB)", | |
| info=( | |
| "Drives the instrument harder or softer, which changes its tone as " | |
| "well as its level." | |
| )), | |
| ] | |
| output_components = [ | |
| gr.Audio(type="filepath", label="Timbre-transferred audio").set_info(( | |
| "The input resynthesized in the chosen instrument's timbre." | |
| )), | |
| ] | |
| build_endpoint( | |
| model_card=model_card, | |
| input_components=input_components, | |
| output_components=output_components, | |
| process_fn=process_fn, | |
| ) | |
| demo.queue().launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", "7860")), show_error=True) | |