devalang_wasm/engine/audio/interpreter/driver/
mod.rs1use crate::engine::audio::events::AudioEventList;
2use crate::engine::events::EventRegistry;
3use crate::engine::functions::FunctionRegistry;
4use crate::engine::special_vars::{SpecialVarContext, is_special_var, resolve_special_var};
5use crate::engine::audio::events::SynthDefinition;
6use crate::language::syntax::ast::{Statement, Value};
7use crate::language::addons::registry::BankRegistry;
8use anyhow::Result;
10use std::collections::HashMap;
11
12pub mod collector;
13pub mod handler;
14pub mod extractor;
15pub mod renderer;
16
17pub struct AudioInterpreter {
18 pub sample_rate: u32,
19 pub bpm: f32,
20 pub function_registry: FunctionRegistry,
21 pub events: AudioEventList,
22 pub variables: HashMap<String, Value>,
23 pub groups: HashMap<String, Vec<Statement>>,
24 pub banks: BankRegistry,
25 pub cursor_time: f32,
26 pub special_vars: SpecialVarContext,
27 pub event_registry: EventRegistry,
28 current_statement_location: Option<(usize, usize)>, pub suppress_beat_emit: bool,
32}
33
34impl AudioInterpreter {
35 pub fn new(sample_rate: u32) -> Self {
36 Self {
37 sample_rate,
38 bpm: 120.0,
39 function_registry: FunctionRegistry::new(),
40 events: AudioEventList::new(),
41 variables: HashMap::new(),
42 groups: HashMap::new(),
43 banks: BankRegistry::new(),
44 cursor_time: 0.0,
45 special_vars: SpecialVarContext::new(120.0, sample_rate),
46 event_registry: EventRegistry::new(),
47 current_statement_location: None,
48 suppress_beat_emit: false,
49 }
50 }
51
52 fn handle_trigger(&mut self, entity: &str) -> Result<()> {
54 handler::handle_trigger(self, entity)
56 }
57
58 fn debug_list_banks(&self) {
60 println!("🔍 Available triggers in BankRegistry:");
61 for (bank_name, bank) in self.banks.list_banks() {
62 println!(" Bank: {}", bank_name);
63 for trigger in bank.list_triggers() {
64 println!(" Trigger: {}", trigger);
65 }
66 }
67 }
68
69 pub fn interpret(&mut self, statements: &[Statement]) -> Result<Vec<f32>> {
70 let total_duration = self.calculate_total_duration(statements)?;
72 self.special_vars.total_duration = total_duration;
73 self.special_vars.update_bpm(self.bpm);
74
75 self.collect_events(statements)?;
77
78 self.render_audio()
82 }
83
84 pub fn events(&self) -> &AudioEventList {
86 &self.events
87 }
88
89 pub fn current_statement_location(&self) -> Option<(usize, usize)> {
91 self.current_statement_location
92 }
93
94 pub fn calculate_total_duration(&self, _statements: &[Statement]) -> Result<f32> {
96 Ok(60.0) }
99
100 pub fn collect_events(&mut self, statements: &[Statement]) -> Result<()> {
101 collector::collect_events(self, statements)
103 }
104 pub fn handle_let(&mut self, name: &str, value: &Value) -> Result<()> {
105 handler::handle_let(self, name, value)
106 }
107
108 pub fn extract_audio_event(
109 &mut self,
110 target: &str,
111 context: &crate::engine::functions::FunctionContext,
112 ) -> Result<()> {
113 extractor::extract_audio_event(self, target, context)
115 }
116
117 pub fn render_audio(&self) -> Result<Vec<f32>> {
118 renderer::render_audio(self)
120 }
121
122 pub fn set_bpm(&mut self, bpm: f32) {
123 self.bpm = bpm.max(1.0).min(999.0);
124 }
125
126 pub fn samples_per_beat(&self) -> usize {
127 ((60.0 / self.bpm) * self.sample_rate as f32) as usize
128 }
129
130 pub fn beat_duration(&self) -> f32 {
132 60.0 / self.bpm
133 }
134
135 pub fn execute_print(&self, value: &Value) -> Result<()> {
138 handler::execute_print(self, value)
139 }
140
141 pub fn interpolate_string(&self, template: &str) -> String {
144 let mut result = template.to_string();
145
146 let re = regex::Regex::new(r"\{([a-zA-Z_][a-zA-Z0-9_]*)\}").unwrap();
148
149 for cap in re.captures_iter(template) {
150 let full_match = &cap[0]; let var_name = &cap[1]; if let Some(value) = self.variables.get(var_name) {
154 let replacement = self.value_to_string(value);
155 result = result.replace(full_match, &replacement);
156 } else {
157 result = result.replace(full_match, &format!("<undefined:{}>", var_name));
159 }
160 }
161
162 result
163 }
164
165 fn value_to_string(&self, value: &Value) -> String {
167 match value {
168 Value::String(s) => {
169 s.trim_matches('"').trim_matches('\'').to_string()
171 }
172 Value::Number(n) => {
173 if n.fract() == 0.0 {
175 format!("{:.0}", n)
176 } else {
177 format!("{}", n)
178 }
179 }
180 Value::Boolean(b) => b.to_string(),
181 Value::Array(arr) => {
182 let items: Vec<String> = arr.iter().map(|v| self.value_to_string(v)).collect();
183 format!("[{}]", items.join(", "))
184 }
185 Value::Identifier(id) => id.clone(),
186 _ => format!("{:?}", value),
187 }
188 }
189
190 pub fn execute_if(
192 &mut self,
193 condition: &Value,
194 body: &[Statement],
195 else_body: &Option<Vec<Statement>>,
196 ) -> Result<()> {
197 handler::execute_if(self, condition, body, else_body)
198 }
199
200 pub fn evaluate_condition(&self, condition: &Value) -> Result<bool> {
203 if let Value::Map(map) = condition {
205 let operator = map
206 .get("operator")
207 .and_then(|v| {
208 if let Value::String(s) = v {
209 Some(s.as_str())
210 } else {
211 None
212 }
213 })
214 .unwrap_or("==");
215
216 let left = map
217 .get("left")
218 .ok_or_else(|| anyhow::anyhow!("Missing left operand"))?;
219 let right = map
220 .get("right")
221 .ok_or_else(|| anyhow::anyhow!("Missing right operand"))?;
222
223 let left_val = self.resolve_value(left);
225 let right_val = self.resolve_value(right);
226
227 match operator {
229 "==" => Ok(self.values_equal(&left_val, &right_val)),
230 "!=" => Ok(!self.values_equal(&left_val, &right_val)),
231 "<" => self.compare_values(&left_val, &right_val, std::cmp::Ordering::Less),
232 ">" => self.compare_values(&left_val, &right_val, std::cmp::Ordering::Greater),
233 "<=" => {
234 let less =
235 self.compare_values(&left_val, &right_val, std::cmp::Ordering::Less)?;
236 let equal = self.values_equal(&left_val, &right_val);
237 Ok(less || equal)
238 }
239 ">=" => {
240 let greater =
241 self.compare_values(&left_val, &right_val, std::cmp::Ordering::Greater)?;
242 let equal = self.values_equal(&left_val, &right_val);
243 Ok(greater || equal)
244 }
245 _ => Err(anyhow::anyhow!("Unknown operator: {}", operator)),
246 }
247 } else {
248 match condition {
250 Value::Boolean(b) => Ok(*b),
251 Value::Number(n) => Ok(*n != 0.0),
252 Value::String(s) => Ok(!s.is_empty()),
253 _ => Ok(false),
254 }
255 }
256 }
257
258 pub fn resolve_value(&self, value: &Value) -> Value {
260 match value {
261 Value::Identifier(name) => {
262 if is_special_var(name) {
264 if let Some(special_val) = resolve_special_var(name, &self.special_vars) {
265 return special_val;
266 }
267 }
268
269 self.variables.get(name).cloned().unwrap_or(Value::Null)
271 }
272 _ => value.clone(),
273 }
274 }
275
276 pub fn execute_event_handlers(&mut self, event_name: &str) -> Result<()> {
278 handler::execute_event_handlers(self, event_name)
279 }
280
281 pub fn values_equal(&self, left: &Value, right: &Value) -> bool {
283 match (left, right) {
284 (Value::Number(a), Value::Number(b)) => (a - b).abs() < 0.0001,
285 (Value::String(a), Value::String(b)) => a == b,
286 (Value::Boolean(a), Value::Boolean(b)) => a == b,
287 (Value::Null, Value::Null) => true,
288 _ => false,
289 }
290 }
291
292 pub fn compare_values(
294 &self,
295 left: &Value,
296 right: &Value,
297 ordering: std::cmp::Ordering,
298 ) -> Result<bool> {
299 match (left, right) {
300 (Value::Number(a), Value::Number(b)) => {
301 Ok(a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) == ordering)
302 }
303 (Value::String(a), Value::String(b)) => Ok(a.cmp(b) == ordering),
304 _ => Err(anyhow::anyhow!("Cannot compare {:?} and {:?}", left, right)),
305 }
306 }
307
308 pub fn handle_assign(&mut self, target: &str, property: &str, value: &Value) -> Result<()> {
310 handler::handle_assign(self, target, property, value)
311 }
312
313 pub fn extract_synth_def_from_map(&self, map: &HashMap<String, Value>) -> Result<SynthDefinition> {
315 handler::extract_synth_def_from_map(self, map)
316 }
317
318 pub fn handle_load(&mut self, source: &str, alias: &str) -> Result<()> {
320 handler::handle_load(self, source, alias)
321 }
322
323 pub fn handle_bind(&mut self, source: &str, target: &str, options: &Value) -> Result<()> {
325 handler::handle_bind(self, source, target, options)
326 }
327
328 pub fn extract_pattern_data(&self, value: &Value) -> (Option<String>, Option<HashMap<String, f32>>) {
330 handler::extract_pattern_data(self, value)
331 }
332
333 pub fn execute_pattern(
335 &mut self,
336 target: &str,
337 pattern: &str,
338 options: Option<HashMap<String, f32>>,
339 ) -> Result<()> {
340 handler::execute_pattern(self, target, pattern, options)
341 }
342
343 pub fn resolve_sample_uri(&self, target: &str) -> String {
345 handler::resolve_sample_uri(self, target)
346 }
347}