use crate::event::{Event, InterpretableEvent, SourceEvent, StaticEvent};
use ruffbox_synth::building_blocks::{SynthParameterLabel, SynthParameterValue};
use std::collections::HashMap;
use vom_rs::pfa;
pub struct Rule {
pub source: Vec<char>,
pub symbol: char,
pub probability: f32,
pub duration: u64,
}
impl Rule {
pub fn to_pfa_rule(&self) -> pfa::Rule<char> {
pfa::Rule {
source: self.source.clone(),
symbol: self.symbol,
probability: self.probability,
}
}
}
#[derive(Clone)]
pub struct MarkovSequenceGenerator {
pub name: String,
pub generator: pfa::Pfa<char>,
pub event_mapping: HashMap<char, Vec<SourceEvent>>,
pub duration_mapping: HashMap<(char, char), Event>,
pub modified: bool,
pub symbol_ages: HashMap<char, u64>,
pub default_duration: u64,
pub last_transition: Option<pfa::PfaQueryResult<char>>,
pub last_symbol: Option<char>,
}
impl MarkovSequenceGenerator {
pub fn transfer_state(&mut self, other: &MarkovSequenceGenerator) {
if let Some(t) = &other.last_transition {
self.last_transition = Some(t.clone());
self.generator.transfer_state(&other.generator);
}
}
pub fn current_events(&mut self) -> Vec<InterpretableEvent> {
let mut interpretable_events = Vec::new();
if let Some(last_symbol) = &self.last_symbol {
*self.symbol_ages.entry(*last_symbol).or_insert(0) += 1;
if let Some(events) = self.event_mapping.get_mut(last_symbol) {
for e in events.iter_mut() {
interpretable_events.push(match e {
SourceEvent::Sound(e) => InterpretableEvent::Sound(e.get_static()),
SourceEvent::Control(e) => InterpretableEvent::Control(e.clone()),
});
}
} else {
println!("no events for sym {}", last_symbol);
}
}
if self.last_symbol.is_some() && self.last_transition.is_none() {
println!("seems like this generator has reached it's end");
self.last_symbol = None;
}
interpretable_events
}
pub fn current_transition(&mut self) -> StaticEvent {
let tmp_next = if self.last_transition.is_some() {
Some(self.last_transition.as_ref().unwrap().next_symbol)
} else {
None
};
self.last_transition = self.generator.next_transition();
if let Some(trans) = &self.last_transition {
self.last_symbol = Some(trans.last_symbol);
if let Some(dur) = self
.duration_mapping
.get_mut(&(trans.last_symbol, trans.next_symbol))
{
dur.get_static()
} else {
let mut t = Event::with_name("transition".to_string()).get_static();
t.params.insert(
SynthParameterLabel::Duration,
SynthParameterValue::ScalarF32(self.default_duration as f32),
);
t
}
} else {
self.last_symbol = tmp_next;
let mut t = Event::with_name("transition".to_string()).get_static();
t.params.insert(
SynthParameterLabel::Duration,
SynthParameterValue::ScalarF32(self.default_duration as f32),
);
t
}
}
pub fn reached_end_state(&self) -> bool {
self.last_symbol.is_none() && self.last_transition.is_none()
}
pub fn set_modified(&mut self) {
self.modified = true;
}
pub fn is_modified(&self) -> bool {
self.modified
}
pub fn clear_modified(&mut self) {
self.modified = false;
}
}