rust_synth/math/
genetic.rs1use fundsp::hacker::Shared;
10
11use super::harmony::{golden_pentatonic, rand_f32, rand_u32};
12
13pub struct Genome<'a> {
16 pub freq: &'a Shared,
17 pub cutoff: &'a Shared,
18 pub resonance: &'a Shared,
19 pub reverb_mix: &'a Shared,
20 pub pulse_depth: &'a Shared,
21 pub pattern_hits: &'a Shared,
22 pub pattern_rotation: &'a Shared,
23}
24
25pub fn mutate(g: &Genome, seed: &mut u64, strength: f32) {
33 let s = strength.clamp(0.0, 1.0);
34
35 let cur = g.freq.value();
37 let scale = golden_pentatonic(cur);
38 let idx = rand_u32(seed, scale.len() as u32) as usize;
39 g.freq.set_value(scale[idx]);
40
41 let cut_factor = (1.0 + s * 0.8 * rand_f32(seed)).clamp(0.25, 4.0);
43 g.cutoff
44 .set_value((g.cutoff.value() * cut_factor).clamp(40.0, 12000.0));
45
46 let res = (g.resonance.value() + s * 0.15 * rand_f32(seed)).clamp(0.0, 0.55);
49 g.resonance.set_value(res);
50
51 let rev = (g.reverb_mix.value() + s * 0.25 * rand_f32(seed)).clamp(0.0, 1.0);
52 g.reverb_mix.set_value(rev);
53
54 let pulse = (g.pulse_depth.value() + s * 0.2 * rand_f32(seed)).clamp(0.0, 1.0);
55 g.pulse_depth.set_value(pulse);
56
57 let hits = (g.pattern_hits.value() + s * 3.0 * rand_f32(seed)).clamp(1.0, 11.0);
61 g.pattern_hits.set_value(hits);
62 let rot = (g.pattern_rotation.value() + s * 4.0 * rand_f32(seed)).rem_euclid(16.0);
63 g.pattern_rotation.set_value(rot);
64}
65
66pub fn crossover(a: &Genome, b: &Genome, seed: &mut u64) {
69 if rand_u32(seed, 2) == 0 {
70 a.freq.set_value(b.freq.value());
71 }
72 if rand_u32(seed, 2) == 0 {
73 a.cutoff.set_value(b.cutoff.value());
74 }
75 if rand_u32(seed, 2) == 0 {
76 a.resonance.set_value(b.resonance.value());
77 }
78 if rand_u32(seed, 2) == 0 {
79 a.reverb_mix.set_value(b.reverb_mix.value());
80 }
81 if rand_u32(seed, 2) == 0 {
82 a.pulse_depth.set_value(b.pulse_depth.value());
83 }
84 if rand_u32(seed, 2) == 0 {
85 a.pattern_hits.set_value(b.pattern_hits.value());
86 }
87 if rand_u32(seed, 2) == 0 {
88 a.pattern_rotation.set_value(b.pattern_rotation.value());
89 }
90 let cur = a.freq.value();
92 let scale = golden_pentatonic(cur);
93 let idx = rand_u32(seed, scale.len() as u32) as usize;
94 a.freq.set_value(scale[idx]);
95}