1mod arguments;
4mod bindings;
5mod cache;
6mod cast;
7mod error;
8pub mod flops;
9pub mod instantiate;
10mod loops;
11mod lower;
12mod meaning;
13mod offset;
14pub mod overload;
15pub mod query;
16mod refs;
17mod release;
18pub mod render;
19mod schedule;
20mod trace;
21mod typing;
22mod vocabulary;
23
24pub use arguments::{Argument, Arguments, Called, Chosen};
25pub use bindings::Binding;
26pub use cache::{
27 Cache, CacheStats, DEFAULT_SLOT_BYTES, DiskCache, ENGINE_DIR_PREFIX, Entry, Expected, Hash,
28 IO_NANOS_PER_BYTE, Lookup, Medium, MemoryCache, Outcome, PACK_FORMAT, Pack, Payload,
29 PayloadKind, Put, RawF64, SampleCodec, Slots, Tier, Tiered, VecMedium, buffer_key,
30 symbolic_key,
31};
32pub use cast::Cast;
33pub use error::{BindingFault, Diagnostic, EngineError, Located, REGISTRY};
34pub use flops::{Row as FlopRow, Tree as FlopTree};
35pub use loops::{Delay, Shift};
36pub use meaning::{Meaning, meaning};
37pub use offset::Offset;
38pub use query::{Answer, Ask, DEFAULT_FRAME_SECS, Output, Representation};
39pub use refs::{Read, identity, nodes_in, resolve, spectral_sum_of, symbolic_hash};
40pub use render::{
41 Block, Checkpoint, Render, RenderConfig, STREAMED, Silent, Stream, StreamConfig, answer,
42 answer_buffer, ledger_over, render, render_until_silent, render_with_slots, sketch_atom,
43};
44pub use schedule::{Order, Schedule, schedule_from};
45pub use sva_formula::{C64, Codomain, Held, Line, NodeId, SpectralSum, Ty, Var};
46pub use sva_samples::{
47 Alias, AliasBand, BAND_COUNT, BandCrest, BandTrack, Bands, Buffer, Cost, Crest, Detail,
48 EnvelopeFrame, FormantFrame, Frames, Horizon, Label, LedgerEntry, Loudness, LoudnessFrame,
49 MAX_PINNED_FRAME, PSYCHOACOUSTIC_V1, PitchFrame, Profile, Rule, SignalKind, Source, Spectrum,
50 StereoFrame, StereoImage, measure_alias, pinned_frame,
51};
52pub use trace::{Traced, Up, trace};
53pub use typing::{Typing, Value};
54pub use vocabulary::{BUILTINS, MAX_WIDTH, is_builtin, named_may_move, recognized_named};
55
56use sva_ast::Graph;
57
58pub const DEFAULT_SAMPLE_RATE: u32 = 44100;
59
60pub const SOURCE_HASH: &str = env!("SVA_ENGINE_SRC_HASH");
61
62pub const RENDER_FINGERPRINT: u64 = sva_fingerprint::fold(&[
64 sva_ast::SOURCE_HASH,
65 sva_formula::SOURCE_HASH,
66 sva_samples::SOURCE_HASH,
67 SOURCE_HASH,
68]);
69
70pub fn check_structure(graph: &Graph, root: &str) -> Result<(), EngineError> {
72 types(graph, root).map(|_| ())
73}
74
75pub fn types(graph: &Graph, root: &str) -> Result<Typing, EngineError> {
77 let instances = instantiate::instantiate(graph, root)?;
78 let held = instances.instance_of(root)?;
80 let order = schedule::schedule_from(&instances, std::slice::from_ref(&held))?;
81 typing::infer_all(&instances, &order)
82}
83
84pub fn rate_dependent(graph: &Graph, root: &str) -> Result<Vec<String>, EngineError> {
86 let instances = instantiate::instantiate(graph, root)?;
87 Ok(instances
88 .paths()
89 .filter(|p| instances.at(p).is_some_and(|(e, _)| reads_rate(e)))
90 .map(str::to_string)
91 .collect())
92}
93
94fn reads_rate(e: &sva_ast::Expr) -> bool {
95 match e {
96 sva_ast::Expr::Lit(sva_ast::Literal::Samples(_)) => true,
97 sva_ast::Expr::Lit(_) => false,
98 sva_ast::Expr::Var(_) => false,
99 sva_ast::Expr::Bin(_, a, b) => reads_rate(a) || reads_rate(b),
100 sva_ast::Expr::SelfRef { .. } => true,
101 sva_ast::Expr::Ref { arg, binds, .. } => {
102 reads_rate(arg) || binds.iter().any(|(_, v)| reads_rate(v))
103 }
104 sva_ast::Expr::Call { name, args, .. } => {
105 let drawn = name == "rand"
106 && !matches!(
107 args.first(),
108 Some(sva_ast::Arg::Pos(sva_ast::Expr::Lit(_))) | None
109 );
110 drawn
111 || args.iter().any(|a| match a {
112 sva_ast::Arg::Pos(v) | sva_ast::Arg::Named(_, v) => reads_rate(v),
113 })
114 }
115 }
116}