Spaces:
Running on Zero
Running on Zero
File size: 4,624 Bytes
a648319 7a5cbc1 a648319 7a5cbc1 a648319 7a5cbc1 a648319 7a5cbc1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #!/usr/bin/env python3
"""
GN‑v7 – Fast Raw Mode Extractor
================================
Extract raw Koopman (PCA) modes from any audio file.
No ICA, no plots – just the raw modes as WAV files.
"""
import os
import shutil
import tempfile
import zipfile
from typing import List
import gradio as gr
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
import scipy.signal as signal
from sklearn.utils.extmath import randomized_svd
import soundfile as sf
import spaces
# ----------------------------------------------------------------------
# Fast embedding
# ----------------------------------------------------------------------
def embed(x: np.ndarray, dim: int, tau: int) -> np.ndarray:
L = (dim - 1) * tau + 1
win = sliding_window_view(x, L)[:, ::tau]
return win[:, ::-1].copy()
# ----------------------------------------------------------------------
# Fast raw mode extraction using randomized SVD
# ----------------------------------------------------------------------
def extract_raw_modes(x: np.ndarray, dim: int = 32, tau: int = 3, k: int = 8) -> List[np.ndarray]:
"""
Returns list of raw PCA mode signals (time domain) of length same as input.
Each mode is a reconstructed time series from one singular vector.
"""
X = embed(x, dim, tau)
a = np.linalg.norm(X, axis=1) + 1e-9
Xv = X / a[:, None]
U, S, Vt = randomized_svd(Xv, n_components=k, n_iter=5, random_state=0)
W = Vt # shape (k, dim)
Y = Xv @ W.T # activations (T x k)
raw_modes = []
for i in range(k):
mode_embedded = Y[:, i:i+1] @ W[i:i+1, :] # (T, dim)
mode_signal = np.real(mode_embedded[:, 0]) * a
raw_modes.append(mode_signal)
return raw_modes
# ----------------------------------------------------------------------
# Gradio interface (ZeroGPU compatible)
# ----------------------------------------------------------------------
@spaces.GPU
def process_to_raw_modes(file, dim: int, tau: int, k: int):
if file is None:
raise gr.Error("Please upload an audio file.")
try:
sig, fs = sf.read(file)
except Exception as e:
raise gr.Error(f"Failed to read: {e}")
if sig.ndim > 1:
sig = np.mean(sig, axis=1)
target_sr = 16000
if fs != target_sr:
sig = signal.resample_poly(sig, target_sr, fs)
fs = target_sr
sig = sig / (np.max(np.abs(sig)) + 1e-9)
duration = len(sig) / fs
gr.Info(f"Processing {duration:.1f} sec song with dim={dim}, tau={tau}, k={k} ...")
try:
raw_modes = extract_raw_modes(sig, dim=dim, tau=tau, k=k)
except Exception as e:
raise gr.Error(f"Extraction failed: {e}")
temp_dir = tempfile.mkdtemp()
try:
for i, mode in enumerate(raw_modes):
sf.write(os.path.join(temp_dir, f"raw_mode_{i:02d}.wav"), mode, fs)
zip_path = os.path.join(tempfile.gettempdir(), "raw_modes.zip")
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for fname in os.listdir(temp_dir):
zf.write(os.path.join(temp_dir, fname), arcname=fname)
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
preview_audio = (fs, raw_modes[0])
return preview_audio, zip_path
# ----------------------------------------------------------------------
# UI
# ----------------------------------------------------------------------
with gr.Blocks(title="Fast Raw Mode Extractor", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🔧 Fast Raw Mode Extractor (GN‑v7, PCA only)
Upload your song → get raw Koopman/PCA modes as WAV files.
**No ICA, no plots – just the raw modes.**
These are the `raw_mode_XX.wav` files from the original GN‑v7.
""")
with gr.Row():
with gr.Column():
audio_in = gr.Audio(type="filepath", label="Your song (any length)")
dim_slider = gr.Slider(16, 64, value=32, step=2, label="Embedding dim (lower = faster)")
tau_slider = gr.Slider(1, 8, value=3, step=1, label="Delay tau")
k_slider = gr.Slider(2, 16, value=8, step=1, label="Number of raw modes (k)")
run_btn = gr.Button("Extract Raw Modes", variant="primary")
with gr.Column():
preview = gr.Audio(label="Preview of first raw mode", type="numpy")
zip_output = gr.File(label="📦 Download all raw modes (ZIP)")
run_btn.click(
fn=process_to_raw_modes,
inputs=[audio_in, dim_slider, tau_slider, k_slider],
outputs=[preview, zip_output]
)
if __name__ == "__main__":
demo.launch() |