Etterna 0.74.4
Loading...
Searching...
No Matches
CJ.h
1#pragma once
2#include "../../PatternModHelpers.h"
3
6struct CJMod
7{
8 const CalcPatternMod _pmod = CJ;
9 // const std::vector<CalcPatternMod> _dbg = { CJS, CJJ };
10 const std::string name = "CJMod";
11
12#pragma region params
13
14 float min_mod = 0.6F;
15 float max_mod = 1.F;
16 float mod_base = 0.4F;
17 float prop_buffer = 1.F;
18
19 float total_prop_min = min_mod;
20 float total_prop_max = max_mod;
21 float total_prop_scaler = 5.428F;
22
23 float jack_base = 2.F;
24 float jack_min = 0.625F;
25 float jack_max = 1.F;
26 float jack_scaler = 1.F;
27
28 float not_jack_pool = 1.2F;
29 float not_jack_min = 0.4F;
30 float not_jack_max = 1.F;
31 float not_jack_scaler = 1.F;
32
33 float vibro_flag = 1.F;
34 float decay_factor = 0.1F;
35
36 const std::vector<std::pair<std::string, float*>> _params{
37 { "min_mod", &min_mod },
38 { "max_mod", &max_mod },
39 { "mod_base", &mod_base },
40 { "prop_buffer", &prop_buffer },
41
42 { "total_prop_min", &total_prop_min },
43 { "total_prop_max", &total_prop_max },
44 { "total_prop_scaler", &total_prop_scaler },
45
46 { "jack_base", &jack_base },
47 { "jack_min", &jack_min },
48 { "jack_max", &jack_max },
49 { "jack_scaler", &jack_scaler },
50
51 { "not_jack_pool", &not_jack_pool },
52 { "not_jack_min", &not_jack_min },
53 { "not_jack_max", &not_jack_max },
54 { "not_jack_scaler", &not_jack_scaler },
55
56 { "vibro_flag", &vibro_flag },
57 { "decay_factor", &decay_factor },
58 };
59#pragma endregion params and param map
60
61 float total_prop = 0.F;
62 float jack_prop = 0.F;
63 float not_jack_prop = 0.F;
64 float pmod = min_mod;
65 float t_taps = 0.F;
66 float last_mod = 0.F;
67
68 void full_reset()
69 {
70 last_mod = min_mod;
71 }
72
73 void decay_mod()
74 {
75 pmod = std::clamp(last_mod - decay_factor, min_mod, max_mod);
76 last_mod = pmod;
77 }
78
79 // inline void set_dbg(std::vector<float> doot[], const int& i)
80 //{
81 // doot[CJS][i] = not_jack_prop;
82 // doot[CJJ][i] = jack_prop;
83 //}
84
85 auto operator()(const metaItvInfo& mitvi) -> float
86 {
87 const auto& itvi = mitvi._itvi;
88
89 if (itvi.total_taps == 0) {
90 return neutral;
91 }
92
93 // no chords
94 if (itvi.chord_taps == 0) {
95 decay_mod();
96 return pmod;
97 }
98
99 t_taps = static_cast<float>(itvi.total_taps);
100
101 // we have at least 1 chord we want to give a little leeway for single
102 // taps but not too much or sections of [12]4[123] [123]4[23] will be
103 // flagged as chordjack when they're really just broken chordstream, and
104 // we also want to give enough leeway so that hyperdense chordjacks at
105 // lower bpms aren't automatically rated higher than more sparse jacks
106 // at higher bpms
107 total_prop = static_cast<float>(static_cast<float>(itvi.chord_taps) +
108 prop_buffer) /
109 (t_taps - prop_buffer) * total_prop_scaler;
110 total_prop =
111 std::clamp(fastsqrt(total_prop), total_prop_min, total_prop_max);
112
113 // make sure there's at least a couple of jacks
114 jack_prop =
115 std::clamp(static_cast<float>(mitvi.actual_jacks_cj) - jack_base,
116 jack_min,
117 jack_max);
118
119 // explicitly detect broken chordstream type stuff so we can give more
120 // leeway to single note jacks brop_two_return_of_brop_electric_bropaloo
121 not_jack_prop = std::clamp(
122 not_jack_pool -
123 (static_cast<float>(static_cast<float>(mitvi.definitely_not_jacks) *
124 not_jack_scaler) /
125 t_taps),
126 not_jack_min,
127 not_jack_max);
128
129 pmod =
130 std::clamp(total_prop * jack_prop * not_jack_prop, min_mod, max_mod);
131
132 // ITS JUST VIBRO THEN(unique note permutations per interval < 3 ), use
133 // this other places ?
134 if (mitvi.basically_vibro) {
135 if (mitvi.num_var == 1) {
136 pmod *= 0.5F * vibro_flag;
137 } else if (mitvi.num_var == 2) {
138 pmod *= 0.9F * vibro_flag;
139 } else if (mitvi.num_var == 3) {
140 pmod *= 0.95F * vibro_flag;
141 }
142 }
143
144 // set for decay
145 last_mod = pmod;
146
147 return pmod;
148 }
149};
Definition CJ.h:7
Definition MetaIntervalInfo.h:20