use crate::language::syntax::ast::Value;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Node {
pub name: String,
pub alias: Option<String>,
pub effects: Option<Value>, }
#[derive(Debug, Clone)]
pub enum Connection {
Route {
source: String,
destination: String,
gain: f32,
},
Duck {
source: String,
destination: String,
effect_params: Value, },
Sidechain {
source: String,
destination: String,
effect_params: Value, },
}
#[derive(Debug, Clone)]
pub struct AudioGraph {
pub nodes: HashMap<String, Node>,
pub connections: Vec<Connection>,
pub master_node: String,
}
impl AudioGraph {
pub fn new() -> Self {
let mut nodes = HashMap::new();
nodes.insert(
"$master".to_string(),
Node {
name: "$master".to_string(),
alias: None,
effects: None,
},
);
Self {
nodes,
connections: Vec::new(),
master_node: "$master".to_string(),
}
}
pub fn add_node(&mut self, name: String, alias: Option<String>, effects: Option<Value>) {
self.nodes.insert(
name.clone(),
Node {
name,
alias,
effects,
},
);
}
pub fn add_connection(&mut self, connection: Connection) {
self.connections.push(connection);
}
pub fn from_routing_setup(
routing_setup: &crate::engine::audio::interpreter::driver::RoutingSetup,
) -> Self {
let mut graph = AudioGraph::new();
for (name, node_config) in &routing_setup.nodes {
graph.add_node(
name.clone(),
node_config.alias.clone(),
node_config.effects.clone(),
);
}
for route in &routing_setup.routes {
let gain = if let Some(Value::Map(effects_map)) = &route.effects {
if let Some(Value::Map(volume_map)) = effects_map.get("volume") {
if let Some(Value::Number(g)) = volume_map.get("gain") {
*g
} else {
1.0
}
} else if let Some(Value::Number(g)) = effects_map.get("volume") {
*g
} else {
1.0
}
} else {
1.0
};
graph.add_connection(Connection::Route {
source: route.source.clone(),
destination: route.destination.clone(),
gain,
});
}
for duck in &routing_setup.ducks {
graph.add_connection(Connection::Duck {
source: duck.source.clone(),
destination: duck.destination.clone(),
effect_params: duck.effect.clone(),
});
}
for sidechain in &routing_setup.sidechains {
graph.add_connection(Connection::Sidechain {
source: sidechain.source.clone(),
destination: sidechain.destination.clone(),
effect_params: sidechain.effect.clone(),
});
}
graph
}
pub fn get_outgoing_routes(&self, node_name: &str) -> Vec<&Connection> {
self.connections
.iter()
.filter(|conn| match conn {
Connection::Route { source, .. } => source == node_name,
_ => false,
})
.collect()
}
pub fn get_incoming_ducks(&self, node_name: &str) -> Vec<&Connection> {
self.connections
.iter()
.filter(|conn| match conn {
Connection::Duck { source, .. } if source == node_name => true,
_ => false,
})
.collect()
}
pub fn get_incoming_sidechains(&self, node_name: &str) -> Vec<&Connection> {
self.connections
.iter()
.filter(|conn| match conn {
Connection::Sidechain { source, .. } if source == node_name => true,
_ => false,
})
.collect()
}
pub fn has_node(&self, node_name: &str) -> bool {
self.nodes.contains_key(node_name)
}
pub fn node_names(&self) -> Vec<String> {
self.nodes.keys().cloned().collect()
}
#[allow(dead_code)]
pub fn debug_print(&self) {
}
}
impl Default for AudioGraph {
fn default() -> Self {
Self::new()
}
}