Skip to main content

sim_lib_audio_dsp/
runtime.rs

1use sim_kernel::{Cx, Lib, LibManifest, Linker, LoadCx, Result, Symbol};
2use sim_lib_core::{SurfaceField, SurfacePackLib, SurfacePackSpec, SurfaceValueSpec, install_once};
3
4use crate::cookbook_runtime::{audio_dsp_cookbook_exports, install_audio_dsp_cookbook_functions};
5
6const AUDIO_DSP_LIB_ID: &str = "audio-dsp";
7
8/// Host-registered lib exporting the reusable DSP processor cards, built on the
9/// shared [`SurfacePackLib`] substrate.
10pub struct AudioDspLib;
11
12impl Lib for AudioDspLib {
13    fn manifest(&self) -> LibManifest {
14        let mut manifest = audio_dsp_pack().manifest();
15        manifest.exports.extend(audio_dsp_cookbook_exports());
16        manifest
17    }
18
19    fn load(&self, cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
20        audio_dsp_pack().load(cx, linker)?;
21        install_audio_dsp_cookbook_functions(cx, linker)
22    }
23}
24
25/// Installs [`AudioDspLib`] into the context once, idempotently.
26pub fn install_audio_dsp_lib(cx: &mut Cx) -> Result<()> {
27    install_once(cx, &AudioDspLib)?;
28    Ok(())
29}
30
31/// Returns the namespaced symbols for every DSP processor card this lib exports.
32pub fn audio_dsp_symbols() -> Vec<Symbol> {
33    [
34        "SmoothValue",
35        "SmoothedGain",
36        "Gain",
37        "Pan",
38        "DcBlocker",
39        "OnePoleFilter",
40        "BiquadFilter",
41        "StateVariableFilter",
42        "DelayProcessor",
43        "FractionalDelay",
44        "CombFilter",
45        "AllPassFilter",
46        "Chorus",
47        "Flanger",
48        "Vibrato",
49        "Waveshaper",
50        "SoftClipper",
51        "Compressor",
52        "Limiter",
53        "Gate",
54        "OversamplingWrapper",
55    ]
56    .into_iter()
57    .map(|name| Symbol::qualified(AUDIO_DSP_LIB_ID, name))
58    .collect()
59}
60
61fn audio_dsp_pack() -> SurfacePackLib {
62    SurfacePackLib {
63        spec: SurfacePackSpec {
64            lib_id: Symbol::new(AUDIO_DSP_LIB_ID),
65            values: audio_dsp_symbols()
66                .into_iter()
67                .map(|symbol| SurfaceValueSpec {
68                    symbol: symbol.clone(),
69                    fields: vec![
70                        (Symbol::new("symbol"), SurfaceField::Symbol(symbol)),
71                        (
72                            Symbol::new("layer"),
73                            SurfaceField::Str(AUDIO_DSP_LIB_ID.to_owned()),
74                        ),
75                        (
76                            Symbol::new("kind"),
77                            SurfaceField::Str("audio-graph-processor".to_owned()),
78                        ),
79                        (
80                            Symbol::new("role"),
81                            SurfaceField::Str(
82                                "reusable pure Rust DSP processor descriptor".to_owned(),
83                            ),
84                        ),
85                        (
86                            Symbol::new("contract"),
87                            SurfaceField::Str("Processor".to_owned()),
88                        ),
89                    ],
90                })
91                .collect(),
92        },
93    }
94}