1use sva_formula::{Line, SpectralSum};
4use sva_samples::{
5 Alias, Bands, Buffer, Consumes, Crest, EnvelopeFrame, FormantFrame, LedgerEntry, Loudness,
6 Onsets, PitchFrame, Source, Spectrum, StereoImage,
7};
8
9use crate::arguments::Arguments;
10use crate::bindings::Binding;
11
12pub const DEFAULT_FRAME_SECS: f64 = 0.05;
14
15#[derive(Clone, Copy, Debug, PartialEq)]
16pub enum Representation {
17 Lines,
18 Atoms,
19 Spectrum {
20 max_peaks: usize,
21 frame_secs: Option<f64>,
22 },
23 Envelope {
24 frame_secs: Option<f64>,
25 },
26 Derivative,
27 Samples,
28 Ledger {
29 depth: usize,
30 },
31 Pitch {
32 max_notes: usize,
33 frame_secs: f64,
34 },
35 Formants {
36 max_formants: usize,
37 frame_secs: f64,
38 },
39 Stereo {
40 frame_secs: f64,
41 },
42 Bands,
43 Crest,
44 Loudness,
45 Onsets,
46 Alias {
47 oversample: u32,
48 },
49 Bindings,
50 Arguments,
51 Flops,
52}
53
54#[derive(Clone, Debug, PartialEq)]
56pub struct Ask {
57 pub node: String,
58 pub representation: Representation,
59}
60
61#[derive(Clone, Debug, PartialEq)]
62pub enum Output {
63 Lines(Vec<Line>),
64 Atoms(Vec<String>),
65 Symbolic(Box<SpectralSum>),
66 Samples(Box<Buffer>),
67 Spectrum(Box<Spectrum>),
68 Envelope(Vec<EnvelopeFrame>),
69 Pitch(Vec<PitchFrame>),
70 Formants(Vec<FormantFrame>),
71 Stereo(Box<StereoImage>),
72 Bands(Box<Bands>),
73 Crest(Box<Crest>),
74 Loudness(Box<Loudness>),
75 Onsets(Box<Onsets>),
76 Alias(Box<Alias>),
77 Ledger(Vec<LedgerEntry>),
78 Bindings(Vec<Binding>),
79 Arguments(Vec<Arguments>),
80 Flops(Box<crate::flops::Tree>),
81}
82
83#[derive(Clone, Debug, PartialEq)]
86pub struct Answer {
87 pub value: Output,
88 pub source: Source,
89 pub profile: &'static str,
90 pub rate: Option<u32>,
91 pub dropped: Vec<sva_formula::Line>,
93 pub tail_db: Option<f64>,
94}
95
96impl Answer {
97 pub fn whole(
98 value: Output,
99 source: Source,
100 profile: &'static str,
101 rate: Option<u32>,
102 ) -> Answer {
103 Answer {
104 value,
105 source,
106 profile,
107 rate,
108 dropped: Vec::new(),
109 tail_db: None,
110 }
111 }
112}
113
114impl Representation {
115 pub fn name(self) -> &'static str {
116 match self {
117 Representation::Lines => "lines",
118 Representation::Atoms => "atoms",
119 Representation::Spectrum { .. } => "spectrum",
120 Representation::Envelope { .. } => "envelope",
121 Representation::Derivative => "derivative",
122 Representation::Samples => "samples",
123 Representation::Ledger { .. } => "ledger",
124 Representation::Pitch { .. } => "pitch",
125 Representation::Formants { .. } => "formants",
126 Representation::Stereo { .. } => "stereo",
127 Representation::Bands => "bands",
128 Representation::Crest => "crest",
129 Representation::Loudness => "loudness",
130 Representation::Onsets => "onsets",
131 Representation::Alias { .. } => "alias",
132 Representation::Bindings => "bindings",
133 Representation::Arguments => "arguments",
134 Representation::Flops => "flops",
135 }
136 }
137
138 pub fn consumes(self, closed: bool) -> Consumes {
141 match self {
142 Representation::Lines | Representation::Atoms => Consumes::ClosedForm,
143 Representation::Spectrum { .. }
144 | Representation::Envelope { .. }
145 | Representation::Derivative
146 | Representation::Pitch { .. }
147 if closed =>
148 {
149 Consumes::ClosedForm
150 }
151 Representation::Bindings | Representation::Arguments | Representation::Flops => {
153 Consumes::ClosedForm
154 }
155 _ => Consumes::Buffer,
156 }
157 }
158
159 pub fn off_samples(self, sampled: bool) -> bool {
161 let graph = matches!(
162 self,
163 Representation::Alias { .. } | Representation::Ledger { .. }
164 );
165 !graph && self.consumes(!sampled) == Consumes::Buffer
166 }
167
168 pub fn from_name(name: &str) -> Option<Representation> {
169 Some(match name {
170 "lines" => Representation::Lines,
171 "atoms" => Representation::Atoms,
172 "spectrum" => Representation::Spectrum {
173 max_peaks: 16,
174 frame_secs: None,
175 },
176 "envelope" => Representation::Envelope { frame_secs: None },
177 "derivative" => Representation::Derivative,
178 "samples" => Representation::Samples,
179 "ledger" => Representation::Ledger { depth: 3 },
180 "pitch" => Representation::Pitch {
181 max_notes: 6,
182 frame_secs: DEFAULT_FRAME_SECS,
183 },
184 "formants" => Representation::Formants {
185 max_formants: 5,
186 frame_secs: DEFAULT_FRAME_SECS,
187 },
188 "stereo" => Representation::Stereo {
189 frame_secs: DEFAULT_FRAME_SECS,
190 },
191 "bands" => Representation::Bands,
192 "crest" => Representation::Crest,
193 "loudness" => Representation::Loudness,
194 "onsets" => Representation::Onsets,
195 "alias" => Representation::Alias { oversample: 4 },
196 "bindings" => Representation::Bindings,
197 "arguments" => Representation::Arguments,
198 "flops" => Representation::Flops,
199 _ => return None,
200 })
201 }
202}