Spaces:
Running on Zero
Running on Zero
Keep a lossless container
Browse filesReturns a FLAC or AIFF input in its own container. It also imports spaces plainly, since it is always installed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- app.py +2 -13
- stable_audio_runtime.py +9 -3
app.py
CHANGED
|
@@ -1,21 +1,10 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
|
|
|
|
|
|
| 3 |
import gradio as gr
|
| 4 |
import soundfile as sf
|
| 5 |
|
| 6 |
-
try:
|
| 7 |
-
import spaces
|
| 8 |
-
except ImportError:
|
| 9 |
-
class spaces:
|
| 10 |
-
class GPU:
|
| 11 |
-
def __init__(self, func=None, duration=180):
|
| 12 |
-
self.func = func
|
| 13 |
-
|
| 14 |
-
def __call__(self, *args, **kwargs):
|
| 15 |
-
if self.func is not None:
|
| 16 |
-
return self.func(*args, **kwargs)
|
| 17 |
-
return args[0]
|
| 18 |
-
|
| 19 |
from pyharp import ModelCard, build_endpoint
|
| 20 |
from pyharp.tags import Subcategory
|
| 21 |
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
+
import spaces # imported first, as ZeroGPU requires
|
| 4 |
+
|
| 5 |
import gradio as gr
|
| 6 |
import soundfile as sf
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
from pyharp import ModelCard, build_endpoint
|
| 9 |
from pyharp.tags import Subcategory
|
| 10 |
|
stable_audio_runtime.py
CHANGED
|
@@ -95,7 +95,12 @@ def _load_audio(path: str):
|
|
| 95 |
return int(sample_rate), audio.to(torch.float32)
|
| 96 |
|
| 97 |
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
import soundfile as sf
|
| 100 |
import torch
|
| 101 |
|
|
@@ -106,7 +111,7 @@ def _save_audio(output, sample_rate: int) -> str:
|
|
| 106 |
|
| 107 |
OUTPUT_ROOT.mkdir(parents=True, exist_ok=True)
|
| 108 |
output_dir = Path(tempfile.mkdtemp(dir=OUTPUT_ROOT))
|
| 109 |
-
output_path = output_dir / "stable_audio_3_edit
|
| 110 |
sf.write(output_path, output, sample_rate, subtype="PCM_16")
|
| 111 |
return str(output_path)
|
| 112 |
|
|
@@ -178,4 +183,5 @@ def edit_audio(
|
|
| 178 |
# Returned at the input's rate rather than the one the model runs at
|
| 179 |
if source_rate != sample_rate:
|
| 180 |
output = torchaudio.functional.resample(output.float(), sample_rate, source_rate)
|
| 181 |
-
|
|
|
|
|
|
| 95 |
return int(sample_rate), audio.to(torch.float32)
|
| 96 |
|
| 97 |
|
| 98 |
+
# A lossless input keeps its container. A lossy one comes back as WAV, since encoding the result
|
| 99 |
+
# lossily again would expose the artifacts of the first encode and add a second set.
|
| 100 |
+
LOSSLESS = {".wav", ".flac", ".aiff", ".aif"}
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def _save_audio(output, sample_rate: int, ext: str = ".wav") -> str:
|
| 104 |
import soundfile as sf
|
| 105 |
import torch
|
| 106 |
|
|
|
|
| 111 |
|
| 112 |
OUTPUT_ROOT.mkdir(parents=True, exist_ok=True)
|
| 113 |
output_dir = Path(tempfile.mkdtemp(dir=OUTPUT_ROOT))
|
| 114 |
+
output_path = output_dir / f"stable_audio_3_edit{ext}"
|
| 115 |
sf.write(output_path, output, sample_rate, subtype="PCM_16")
|
| 116 |
return str(output_path)
|
| 117 |
|
|
|
|
| 183 |
# Returned at the input's rate rather than the one the model runs at
|
| 184 |
if source_rate != sample_rate:
|
| 185 |
output = torchaudio.functional.resample(output.float(), sample_rate, source_rate)
|
| 186 |
+
input_ext = Path(audio_path).suffix.lower()
|
| 187 |
+
return _save_audio(output, source_rate, input_ext if input_ext in LOSSLESS else ".wav")
|