oxihuman_morph/
voice_driven_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct AudioBandMapping {
10 pub band_hz_low: f32,
11 pub band_hz_high: f32,
12 pub morph_index: usize,
13 pub gain: f32,
14}
15
16#[derive(Debug, Clone)]
18pub struct VoiceDrivenMorph {
19 pub mappings: Vec<AudioBandMapping>,
20 pub sample_rate: u32,
21 pub morph_count: usize,
22 pub enabled: bool,
23 pub smoothing: f32,
24}
25
26impl VoiceDrivenMorph {
27 pub fn new(morph_count: usize, sample_rate: u32) -> Self {
28 VoiceDrivenMorph {
29 mappings: Vec::new(),
30 sample_rate,
31 morph_count,
32 enabled: true,
33 smoothing: 0.1,
34 }
35 }
36}
37
38pub fn new_voice_driven_morph(morph_count: usize, sample_rate: u32) -> VoiceDrivenMorph {
40 VoiceDrivenMorph::new(morph_count, sample_rate)
41}
42
43pub fn vdm_add_mapping(vdm: &mut VoiceDrivenMorph, mapping: AudioBandMapping) {
45 vdm.mappings.push(mapping);
46}
47
48pub fn vdm_process(vdm: &VoiceDrivenMorph, _audio_frame: &[f32]) -> Vec<f32> {
50 vec![0.0; vdm.morph_count]
52}
53
54pub fn vdm_set_smoothing(vdm: &mut VoiceDrivenMorph, smoothing: f32) {
56 vdm.smoothing = smoothing.clamp(0.0, 1.0);
57}
58
59pub fn vdm_set_enabled(vdm: &mut VoiceDrivenMorph, enabled: bool) {
61 vdm.enabled = enabled;
62}
63
64pub fn vdm_mapping_count(vdm: &VoiceDrivenMorph) -> usize {
66 vdm.mappings.len()
67}
68
69pub fn vdm_to_json(vdm: &VoiceDrivenMorph) -> String {
71 format!(
72 r#"{{"morph_count":{},"sample_rate":{},"mappings":{},"smoothing":{},"enabled":{}}}"#,
73 vdm.morph_count,
74 vdm.sample_rate,
75 vdm.mappings.len(),
76 vdm.smoothing,
77 vdm.enabled
78 )
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_new_morph_count() {
87 let v = new_voice_driven_morph(8, 44100);
88 assert_eq!(v.morph_count, 8 ,);
89 }
90
91 #[test]
92 fn test_sample_rate_stored() {
93 let v = new_voice_driven_morph(4, 48000);
94 assert_eq!(v.sample_rate, 48000 ,);
95 }
96
97 #[test]
98 fn test_process_output_length() {
99 let v = new_voice_driven_morph(6, 44100);
100 let out = vdm_process(&v, &[0.0; 512]);
101 assert_eq!(out.len(), 6 ,);
102 }
103
104 #[test]
105 fn test_add_mapping() {
106 let mut v = new_voice_driven_morph(4, 44100);
107 vdm_add_mapping(
108 &mut v,
109 AudioBandMapping {
110 band_hz_low: 80.0,
111 band_hz_high: 200.0,
112 morph_index: 0,
113 gain: 1.0,
114 },
115 );
116 assert_eq!(vdm_mapping_count(&v), 1 ,);
117 }
118
119 #[test]
120 fn test_smoothing_clamped() {
121 let mut v = new_voice_driven_morph(4, 44100);
122 vdm_set_smoothing(&mut v, 2.0);
123 assert!((v.smoothing - 1.0).abs() < 1e-6, );
124 }
125
126 #[test]
127 fn test_smoothing_clamped_low() {
128 let mut v = new_voice_driven_morph(4, 44100);
129 vdm_set_smoothing(&mut v, -1.0);
130 assert!((v.smoothing).abs() < 1e-6, );
131 }
132
133 #[test]
134 fn test_set_enabled() {
135 let mut v = new_voice_driven_morph(2, 44100);
136 vdm_set_enabled(&mut v, false);
137 assert!(!v.enabled ,);
138 }
139
140 #[test]
141 fn test_to_json_contains_morph_count() {
142 let v = new_voice_driven_morph(5, 22050);
143 let j = vdm_to_json(&v);
144 assert!(j.contains("\"morph_count\""), );
145 }
146
147 #[test]
148 fn test_enabled_default() {
149 let v = new_voice_driven_morph(1, 44100);
150 assert!(v.enabled ,);
151 }
152
153 #[test]
154 fn test_default_smoothing() {
155 let v = new_voice_driven_morph(1, 44100);
156 assert!((v.smoothing - 0.1).abs() < 1e-5, );
157 }
158}