#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct RetargetMapping {
pub source_idx: usize,
pub target_idx: usize,
pub gain: f32,
pub offset: f32,
}
#[derive(Debug, Clone)]
pub struct ExpressionRetargetMl {
pub mappings: Vec<RetargetMapping>,
pub source_dim: usize,
pub target_dim: usize,
pub enabled: bool,
}
impl ExpressionRetargetMl {
pub fn new(source_dim: usize, target_dim: usize) -> Self {
ExpressionRetargetMl {
mappings: Vec::new(),
source_dim,
target_dim,
enabled: true,
}
}
}
pub fn new_expression_retarget_ml(source_dim: usize, target_dim: usize) -> ExpressionRetargetMl {
ExpressionRetargetMl::new(source_dim, target_dim)
}
pub fn erml_add_mapping(adapter: &mut ExpressionRetargetMl, mapping: RetargetMapping) {
adapter.mappings.push(mapping);
}
pub fn erml_retarget(adapter: &ExpressionRetargetMl, source: &[f32]) -> Vec<f32> {
let mut out = vec![0.0f32; adapter.target_dim];
for m in &adapter.mappings {
if m.source_idx < source.len() && m.target_idx < out.len() {
out[m.target_idx] += source[m.source_idx] * m.gain + m.offset;
}
}
out
}
pub fn erml_mapping_count(adapter: &ExpressionRetargetMl) -> usize {
adapter.mappings.len()
}
pub fn erml_set_enabled(adapter: &mut ExpressionRetargetMl, enabled: bool) {
adapter.enabled = enabled;
}
pub fn erml_to_json(adapter: &ExpressionRetargetMl) -> String {
format!(
r#"{{"source_dim":{},"target_dim":{},"mappings":{},"enabled":{}}}"#,
adapter.source_dim,
adapter.target_dim,
adapter.mappings.len(),
adapter.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_dims() {
let a = new_expression_retarget_ml(10, 15);
assert_eq!(a.source_dim, 10 ,);
assert_eq!(a.target_dim, 15 ,);
}
#[test]
fn test_no_mappings_initially() {
let a = new_expression_retarget_ml(5, 5);
assert_eq!(erml_mapping_count(&a), 0 ,);
}
#[test]
fn test_add_mapping() {
let mut a = new_expression_retarget_ml(5, 5);
erml_add_mapping(
&mut a,
RetargetMapping {
source_idx: 0,
target_idx: 0,
gain: 1.0,
offset: 0.0,
},
);
assert_eq!(erml_mapping_count(&a), 1 ,);
}
#[test]
fn test_retarget_output_length() {
let a = new_expression_retarget_ml(4, 6);
let out = erml_retarget(&a, &[0.5; 4]);
assert_eq!(out.len(), 6 ,);
}
#[test]
fn test_retarget_with_gain() {
let mut a = new_expression_retarget_ml(2, 2);
erml_add_mapping(
&mut a,
RetargetMapping {
source_idx: 0,
target_idx: 0,
gain: 2.0,
offset: 0.0,
},
);
let out = erml_retarget(&a, &[0.5, 0.0]);
assert!((out[0] - 1.0).abs() < 1e-5, );
}
#[test]
fn test_retarget_with_offset() {
let mut a = new_expression_retarget_ml(2, 2);
erml_add_mapping(
&mut a,
RetargetMapping {
source_idx: 0,
target_idx: 0,
gain: 0.0,
offset: 0.3,
},
);
let out = erml_retarget(&a, &[0.0, 0.0]);
assert!((out[0] - 0.3).abs() < 1e-5, );
}
#[test]
fn test_set_enabled() {
let mut a = new_expression_retarget_ml(2, 2);
erml_set_enabled(&mut a, false);
assert!(!a.enabled ,);
}
#[test]
fn test_to_json_contains_dims() {
let a = new_expression_retarget_ml(3, 4);
let j = erml_to_json(&a);
assert!(j.contains("\"source_dim\""), );
}
#[test]
fn test_enabled_default() {
let a = new_expression_retarget_ml(1, 1);
assert!(a.enabled ,);
}
#[test]
fn test_retarget_zeroed_without_mappings() {
let a = new_expression_retarget_ml(3, 3);
let out = erml_retarget(&a, &[1.0, 1.0, 1.0]);
assert!(out.iter().all(|&v| v.abs() < 1e-6), );
}
}