File size: 2,022 Bytes
570b87b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env python3
"""Phase 1 demo: multi-source scene → Ambix WAV → JSON spatial report for AIs."""

from __future__ import annotations

import json
import sys
import tempfile
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from hoa64.audio_io import write_wav
from hoa64.report import report_from_ambix_wav, report_from_scene
from hoa64.stream import SourceSpec, encode_scene
from hoa64.synth import envelope_adsr, tone


def main() -> None:
    sr = 48000
    dur = 0.6
    n = int(sr * dur)
    env = envelope_adsr(n, sr, attack=0.02, release=0.08)

    sources = [
        SourceSpec(0.0, 0.0, tone(440, dur, sr, amplitude=0.45) * env, "front_A4"),
        SourceSpec(90.0, 10.0, tone(554.37, dur, sr, amplitude=0.3) * env, "left_C#5"),
        SourceSpec(-120.0, -5.0, tone(659.25, dur, sr, amplitude=0.2) * env, "backright_E5"),
    ]

    print("=== Synthetic multi-source scene ===")
    for s in sources:
        print(f"  {s.label}: az={s.azimuth_deg}° el={s.elevation_deg}°")

    rep = report_from_scene(sources, sr, max_order=3)
    print("\n" + rep.one_liner())
    print(f"sources_hint: {json.dumps(rep.sources_hint, indent=2)}")
    if rep.bands:
        print("bands (first 3):")
        for b in rep.bands[:3]:
            print(
                f"  {b['band_hz']}: DOA ({b['doa_az_deg']:.1f},{b['doa_el_deg']:.1f}) "
                f"E={b['energy']:.3g}"
            )

    out_dir = Path(tempfile.mkdtemp(prefix="hoa64_p1_"))
    wav_path = out_dir / "scene_ambix4.wav"
    json_path = out_dir / "spatial_report.json"

    hoa = encode_scene(sources, max_order=3)
    write_wav(wav_path, hoa[:4], sr)
    rep.save(json_path)

    # Reload as Ambix and re-analyze
    rep2 = report_from_ambix_wav(wav_path, max_order=1)
    print(f"\nFrom written Ambix WAV: {rep2.one_liner()}")
    print(f"\nArtifacts:\n  {wav_path}\n  {json_path}")
    print("\nPhase 1: audio path + JSON report for other models — live.")


if __name__ == "__main__":
    main()