Skip to main content

sim_lib_audio_graph_live/
runtime.rs

1use sim_kernel::{
2    AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol, Version,
3};
4
5use crate::{
6    lan_buffered_audio_preview_profile, lan_render_return_profile, live_clock_symbol,
7    realtime_local_audio_profile,
8};
9
10const AUDIO_GRAPH_LIVE_LIB_ID: &str = "audio-graph-live";
11
12/// Loadable library that registers the live audio graph surface with a runtime.
13pub struct AudioGraphLiveLib;
14
15impl Lib for AudioGraphLiveLib {
16    fn manifest(&self) -> LibManifest {
17        LibManifest {
18            id: Symbol::new(AUDIO_GRAPH_LIVE_LIB_ID),
19            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
20            abi: AbiVersion { major: 0, minor: 1 },
21            target: LibTarget::HostRegistered,
22            requires: Vec::new(),
23            capabilities: Vec::new(),
24            exports: live_symbols()
25                .into_iter()
26                .map(|symbol| Export::Value { symbol })
27                .collect(),
28        }
29    }
30
31    fn load(&self, cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
32        for symbol in live_symbols() {
33            linker.value(symbol.clone(), live_value(cx, symbol)?)?;
34        }
35        Ok(())
36    }
37}
38
39/// Installs [`AudioGraphLiveLib`] into the context once, idempotently.
40pub fn install_audio_graph_live_lib(cx: &mut Cx) -> Result<()> {
41    sim_lib_core::install_once(cx, &AudioGraphLiveLib).map(|_| ())
42}
43
44fn live_symbols() -> Vec<Symbol> {
45    vec![
46        Symbol::qualified("stream", "LiveGraphRunner"),
47        Symbol::qualified("stream", "LiveControlToAudioQueue"),
48        Symbol::qualified("stream", "LiveAudioToControlQueue"),
49        Symbol::qualified("stream", "LivePlacementSite"),
50        Symbol::qualified("stream", "LivePlacedNode"),
51        Symbol::qualified("stream", "LiveTransportClock"),
52        Symbol::qualified("stream", "RealtimeLocalAudioProfile"),
53        Symbol::qualified("stream", "LanBufferedAudioPreviewProfile"),
54        Symbol::qualified("stream", "LanRenderReturnProfile"),
55    ]
56}
57
58fn live_value(cx: &mut sim_kernel::LoadCx, symbol: Symbol) -> Result<sim_kernel::Value> {
59    let role = match symbol.name.as_ref() {
60        "LiveGraphRunner" => "live audio graph runner card",
61        "LiveControlToAudioQueue" => "bounded control-to-audio queue card",
62        "LiveAudioToControlQueue" => "bounded audio-to-control queue card",
63        "LivePlacementSite" => "local live placement site card",
64        "LivePlacedNode" => "placed live audio node card",
65        "LiveTransportClock" => "live stream-clock transport card",
66        "RealtimeLocalAudioProfile" => "realtime local audio transport profile card",
67        "LanBufferedAudioPreviewProfile" => "LAN buffered audio preview profile card",
68        "LanRenderReturnProfile" => "LAN render return profile card",
69        _ => "live audio graph card",
70    };
71    let profile = match symbol.name.as_ref() {
72        "LanBufferedAudioPreviewProfile" => lan_buffered_audio_preview_profile(),
73        "LanRenderReturnProfile" => lan_render_return_profile(),
74        _ => realtime_local_audio_profile(),
75    };
76    cx.factory().table(vec![
77        (Symbol::new("symbol"), cx.factory().symbol(symbol)?),
78        (
79            Symbol::new("layer"),
80            cx.factory().string("audio-graph-live".to_owned())?,
81        ),
82        (
83            Symbol::new("kind"),
84            cx.factory().string("plugin".to_owned())?,
85        ),
86        (Symbol::new("role"), cx.factory().string(role.to_owned())?),
87        (
88            Symbol::new("clock"),
89            cx.factory().symbol(live_clock_symbol())?,
90        ),
91        (
92            Symbol::new("bounded"),
93            cx.factory().string("control/audio queues".to_owned())?,
94        ),
95        (
96            Symbol::new("profile"),
97            cx.factory().symbol(profile.name().clone())?,
98        ),
99    ])
100}