Etterna 0.74.4
Loading...
Searching...
No Matches
HS.h
1#pragma once
2#include "../../PatternModHelpers.h"
3#include "../MetaIntervalInfo.h"
4
7struct HSMod
8{
9 const CalcPatternMod _pmod = HS;
10 // const std::vector<CalcPatternMod> _dbg = { HSS, HSJ };
11 const std::string name = "HSMod";
12 const int _tap_size = hand;
13
14#pragma region params
15
16 float min_mod = 0.6F;
17 float max_mod = 1.1F;
18 float mod_base = 0.4F;
19 float prop_buffer = 1.F;
20
21 float total_prop_min = min_mod;
22 float total_prop_max = max_mod;
23
24 // was ~32/7, is higher now to push up light hs (maybe overkill tho)
25 float total_prop_scaler = 5.571F;
26 float total_prop_base = 0.4F;
27
28 float split_hand_pool = 1.6F;
29 float split_hand_min = 0.89F;
30 float split_hand_max = 1.F;
31 float split_hand_scaler = 1.F;
32
33 float jack_pool = 1.35F;
34 float jack_min = 0.5F;
35 float jack_max = 1.F;
36 float jack_scaler = 1.F;
37
38 float decay_factor = 0.05F;
39
40 const std::vector<std::pair<std::string, float*>> _params{
41 { "min_mod", &min_mod },
42 { "max_mod", &max_mod },
43 { "mod_base", &mod_base },
44 { "prop_buffer", &prop_buffer },
45
46 { "total_prop_scaler", &total_prop_scaler },
47 { "total_prop_min", &total_prop_min },
48 { "total_prop_max", &total_prop_max },
49 { "total_prop_base", &total_prop_base },
50
51 { "split_hand_pool", &split_hand_pool },
52 { "split_hand_min", &split_hand_min },
53 { "split_hand_max", &split_hand_max },
54 { "split_hand_scaler", &split_hand_scaler },
55
56 { "jack_pool", &jack_pool },
57 { "jack_min", &jack_min },
58 { "jack_max", &jack_max },
59 { "jack_scaler", &jack_scaler },
60
61 { "decay_factor", &decay_factor },
62 };
63#pragma endregion params and param map
64
65 float total_prop = 0.F;
66 float jumptrill_prop = 0.F;
67 float jack_prop = 0.F;
68 float last_mod = min_mod;
69 float pmod = min_mod;
70 float t_taps = 0.F;
71
72 void full_reset()
73 {
74 last_mod = min_mod;
75 }
76
77 void decay_mod()
78 {
79 pmod = std::clamp(last_mod - decay_factor, min_mod, max_mod);
80 last_mod = pmod;
81 }
82
83 // inline void set_dbg(std::vector<float> doot[], const int& i)
84 //{
85 // doot[HSS][i] = jumptrill_prop;
86 // doot[HSJ][i] = jack_prop;
87 //}
88
89 auto operator()(const metaItvInfo& mitvi) -> float
90 {
91 const auto& itvi = mitvi._itvi;
92
93 // empty interval, don't decay mod or update last_mod
94 if (itvi.total_taps == 0) {
95 return neutral;
96 }
97
98 // look ma no hands
99 if (itvi.taps_by_size.at(_tap_size) == 0) {
100 decay_mod();
101 return pmod;
102 }
103
104 t_taps = static_cast<float>(itvi.total_taps);
105
106 // when bark of dog into canyon scream at you
107 total_prop = total_prop_base +
108 (static_cast<float>((itvi.taps_by_size.at(_tap_size) +
109 itvi.mixed_hs_density_tap_bonus) +
110 prop_buffer) /
111 (t_taps - prop_buffer) * total_prop_scaler);
112 total_prop =
113 std::clamp(fastsqrt(total_prop), total_prop_min, total_prop_max);
114
115 // downscale jumptrills for hs as well
116 jumptrill_prop = std::clamp(
117 split_hand_pool - (static_cast<float>(mitvi.not_hs) / t_taps),
118 split_hand_min,
119 split_hand_max);
120
121 // downscale by jack density rather than upscale, like cj does
122 jack_prop = std::clamp(
123 jack_pool - (static_cast<float>(mitvi.actual_jacks) / t_taps),
124 jack_min,
125 jack_max);
126
127 pmod =
128 std::clamp(total_prop * jumptrill_prop * jack_prop, min_mod, max_mod);
129
130 if (mitvi.dunk_it) {
131 pmod *= 0.99F;
132 }
133
134 // set last mod, we're using it to create a decaying mod that won't
135 // result in extreme spikiness if files alternate between js and
136 // hs/stream
137 last_mod = pmod;
138
139 return pmod;
140 }
141};
Definition HS.h:8
Definition MetaIntervalInfo.h:20