2 Commits

+6 -54
View File
@@ -9,7 +9,6 @@ Audio-Passthrough und Physik-Visualisierung.
import requests, time, argparse, numpy as np, sys, math import requests, time, argparse, numpy as np, sys, math
import threading, json, psutil import threading, json, psutil
from pathlib import Path
from flask import Flask, render_template_string, jsonify, request as flask_request from flask import Flask, render_template_string, jsonify, request as flask_request
try: try:
@@ -29,7 +28,6 @@ disk_dial_uid = None
running = False running = False
current_level = 0 current_level = 0
current_peak = 0 current_peak = 0
SETTINGS_FILE = Path(__file__).with_name("vu1_audio_settings.json")
# ══════════════════════════════════════════════════════════════ # ══════════════════════════════════════════════════════════════
# HTML / CSS / JS — Skeuomorphes VU-Meter # HTML / CSS / JS — Skeuomorphes VU-Meter
@@ -679,8 +677,8 @@ function drawVU(level, peak){
const cy = h - 22; const cy = h - 22;
const radius = Math.min(w * 0.45, h * 0.78); const radius = Math.min(w * 0.45, h * 0.78);
// Scale arc (immer obere Hälfte, links -> rechts) // Scale arc
const arcStart = -2.80; const arcStart = Math.PI + 0.35;
const arcEnd = -0.35; const arcEnd = -0.35;
// Draw scale markings // Draw scale markings
@@ -1382,34 +1380,6 @@ class PhysicsVU:
return self.needle_pos, self.peak_pos return self.needle_pos, self.peak_pos
# ── Persistenz: zuletzt gewählte Audio-Geräte ──
def load_audio_settings():
defaults = {"audio_device_in": None, "audio_device_out": -1}
try:
if not SETTINGS_FILE.exists():
return defaults
data = json.loads(SETTINGS_FILE.read_text(encoding="utf-8"))
in_dev = data.get("audio_device_in", None)
out_dev = data.get("audio_device_out", -1)
if out_dev is None:
out_dev = -1
return {"audio_device_in": in_dev, "audio_device_out": out_dev}
except Exception as e:
print(f"⚠️ Konnte Audio-Settings nicht laden: {e}")
return defaults
def save_audio_settings(in_dev, out_dev):
try:
payload = {
"audio_device_in": in_dev,
"audio_device_out": out_dev if out_dev is not None else -1
}
SETTINGS_FILE.write_text(json.dumps(payload, indent=2), encoding="utf-8")
except Exception as e:
print(f"⚠️ Konnte Audio-Settings nicht speichern: {e}")
# ══════════════════════════════════════════════════════════════ # ══════════════════════════════════════════════════════════════
# Flask Routes # Flask Routes
# ══════════════════════════════════════════════════════════════ # ══════════════════════════════════════════════════════════════
@@ -1457,7 +1427,6 @@ def set_device(which, dev_id):
if meter.start(): if meter.start():
running = True running = True
threading.Thread(target=update_loop, daemon=True).start() threading.Thread(target=update_loop, daemon=True).start()
save_audio_settings(app.config.get('audio_device_in'), app.config.get('audio_device_out', -1))
return jsonify({"ok": True}) return jsonify({"ok": True})
@app.route('/toggle') @app.route('/toggle')
@@ -1597,7 +1566,7 @@ def update_loop():
# ── Main ── # ── Main ──
def main(): def main():
global client, dial_uid, meter, running global client, dial_uid, meter
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--api-key", required=True) parser.add_argument("--api-key", required=True)
@@ -1607,13 +1576,8 @@ def main():
parser.add_argument("--port", type=int, default=8080) parser.add_argument("--port", type=int, default=8080)
args = parser.parse_args() args = parser.parse_args()
saved = load_audio_settings() app.config['audio_device_in'] = args.audio_device
chosen_in = args.audio_device if args.audio_device is not None else saved.get('audio_device_in') app.config['audio_device_out'] = args.output_device
chosen_out = args.output_device if args.output_device is not None else saved.get('audio_device_out', -1)
app.config['audio_device_in'] = chosen_in
app.config['audio_device_out'] = chosen_out if chosen_out is not None else -1
save_audio_settings(app.config['audio_device_in'], app.config['audio_device_out'])
client = VU1Client(api_key=args.api_key) client = VU1Client(api_key=args.api_key)
dials = client.get_dials() dials = client.get_dials()
@@ -1637,19 +1601,7 @@ def main():
globals()['disk_dial_uid'] = others[1] globals()['disk_dial_uid'] = others[1]
print(f"✅ Disk-Dial: ({others[1][:8]}…)") print(f"✅ Disk-Dial: ({others[1][:8]}…)")
out_for_meter = app.config['audio_device_out'] meter = PhysicsVU(device_in=args.audio_device, device_out=args.output_device)
meter = PhysicsVU(
device_in=app.config['audio_device_in'],
device_out=out_for_meter if out_for_meter is not None and out_for_meter >= 0 else None
)
# Auto-Start mit gespeicherten Geräten
if meter.start():
running = True
threading.Thread(target=update_loop, daemon=True).start()
print("▶ Auto-Start aktiv (gespeicherte Audio-Ein-/Ausgänge)")
else:
print("⚠️ Auto-Start fehlgeschlagen; bitte Geräte prüfen und manuell starten.")
print(f"\n🎛️ VU1 Meter Web GUI v3") print(f"\n🎛️ VU1 Meter Web GUI v3")
print(f"{'='*40}") print(f"{'='*40}")