| """Binary search: does the full app crash because of CSS, plots, or something else?""" |
| import os, sys |
| os.environ["SOUNDBROKEN_MOCK"] = "1" |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) |
|
|
| import gradio as gr |
| from audio_analyzer import extract_features |
| from fault_rules import rank_candidates, RULES |
| from json_guard import validate |
| from feature_prompt import build_diagnosis_prompt, SYSTEM_PROMPT |
|
|
| APPLIANCES = list(RULES.keys()) |
|
|
| |
| css_path = os.path.join(os.path.dirname(__file__), "assets", "custom.css") |
| with open(css_path, "r", encoding="utf-8") as f: |
| custom_css = f.read() |
|
|
| print("[test] CSS loaded", flush=True) |
|
|
| |
| def _mock_generate(prompt, candidates, features): |
| import json |
| top = candidates[0] |
| return json.dumps({ |
| "fault": top.name, "urgency": top.urgency, |
| "checks": ["Check component.", "Listen again.", "Call tech."], |
| "safety": "Disconnect power.", "confidence": int(top.weight * 100), |
| }) |
|
|
| print("[test] Building Blocks...", flush=True) |
|
|
| with gr.Blocks(css=custom_css, title="Does It Sound Broken?") as demo: |
| state = gr.State({}) |
| gr.Markdown("# Does It Sound Broken?") |
| with gr.Tabs(): |
| with gr.Tab("Diagnose"): |
| with gr.Row(): |
| with gr.Column(): |
| audio_in = gr.Audio(sources=["microphone","upload"], type="filepath", label="Record audio") |
| appliance = gr.Dropdown(choices=APPLIANCES, value="Washing machine", label="Appliance") |
| diagnose_btn = gr.Button("Diagnose", variant="primary") |
| gr.Examples( |
| examples=[ |
| ["assets/sample_washer_bearing.wav", "Washing machine"], |
| ["assets/sample_fan_imbalanced.wav", "Electric fan"], |
| ], |
| inputs=[audio_in, appliance], |
| ) |
| with gr.Column(): |
| verdict_out = gr.HTML() |
| features_out = gr.Markdown() |
| candidates_out = gr.Markdown() |
|
|
| def diagnose(audio_path, appl, state_dict): |
| if not audio_path: |
| return "<div>Upload audio</div>", "", "", state_dict |
| features = extract_features(audio_path) |
| cands = rank_candidates(features, appl) |
| prompt = build_diagnosis_prompt(features, cands, appl) |
| raw = _mock_generate(prompt, cands, features) |
| result = validate(raw, cands) |
| checks_html = "".join(f"<li>{c}</li>" for c in result.checks) |
| verdict = f"""<div class="verdict" style="border-left:8px solid #FB8C00"> |
| <div class="fault">{result.fault}</div> |
| <div class="conf">{result.confidence}% confidence</div> |
| <ol class="checks">{checks_html}</ol> |
| <div class="safety">{result.safety}</div> |
| </div>""" |
| feat_md = ( |
| f"| Metric | Value |\n|---|---|\n" |
| f"| Loudness | {features.rms_db:.1f} dB |\n" |
| f"| Centroid | {features.spectral_centroid_hz:.0f} Hz |\n" |
| f"| Anomaly | {features.anomaly_score:.2f} |\n" |
| ) |
| cand_md = "\n".join(f"- **{c.name}** ({c.weight:.0%})" for c in cands) |
| state_dict = dict(state_dict or {}) |
| state_dict["last_features"] = features.to_dict() |
| return verdict, feat_md, cand_md, state_dict |
|
|
| diagnose_btn.click(diagnose, [audio_in, appliance, state], |
| [verdict_out, features_out, candidates_out, state]) |
|
|
| with gr.Tab("Compare"): |
| gr.Markdown("Compare before/after") |
|
|
| print("[test] Blocks built OK", flush=True) |
| print("[test] Launching on http://127.0.0.1:8090 ...", flush=True) |
| demo.launch(server_port=8090, server_name="127.0.0.1", show_error=True) |
| print("[test] LAUNCHED!", flush=True) |
|
|