#!/usr/bin/env python3 """ engine_lygo.py – LYGO Resonance Engine Module Importable by app.py. Returns (log, audio_path, downloadable_files). """ import os from pathlib import Path from resonance_engine import ResonanceEngine, PRESETS from utils import safe_sf_write, logger def run_lygo_resonance(image_path, style, seed, duration, noise_filter, enable_ldq, genre_manifold, percussion_mode, perceptual_polish, bpm, swing, export_stems, export_midi): """ Run LYGO Resonance Engine with given parameters. Returns (log_message, audio_path, list_of_files). """ if not image_path or not os.path.exists(image_path): return "❌ No valid image provided.", None, [] # Build config config = { "duration": duration, "random_seed": int(seed) if seed != 0 else None, "verbose": False, "use_ldq": enable_ldq, "genre_manifold": genre_manifold, "percussion_mode": percussion_mode, "perceptual_polish": perceptual_polish, "tempo_bpm": bpm, "swing": swing, "export_stems": export_stems, "export_midi": export_midi, } if noise_filter > 0: config["noise_lowpass_hz"] = noise_filter preset = PRESETS.get(style, {}) config.update(preset) # Initialize and run engine = ResonanceEngine(config) out_path = f"lygo_{Path(image_path).stem}.wav" try: engine.process(image_path, out_path) except Exception as e: logger.error(f"LYGO engine error: {e}", exc_info=True) return f"❌ LYGO Error: {str(e)}", None, [] # Collect files downloadable = [out_path] if export_stems: base = out_path.replace(".wav", "") for suffix in ["noise", "drone", "melody", "glitch"]: stem_path = f"{base}_{suffix}.wav" if os.path.exists(stem_path): downloadable.append(stem_path) if export_midi: mid_path = out_path.replace(".wav", ".mid") if os.path.exists(mid_path): downloadable.append(mid_path) log_msg = ( f"✅ LYGO Resonance Engine complete.\n" f"Output: {out_path}\n" f"LDQ enabled: {enable_ldq}\n" f"Genre: {genre_manifold}\n" f"Percussion: {percussion_mode}\n" f"BPM: {bpm}, Swing: {swing}" ) return log_msg, out_path, downloadable