@@ -3779,61 +3779,28 @@ struct ChaosMod
3779
3779
const std::string name = " ChaosMod" ;
3780
3780
3781
3781
#pragma region params
3782
- float itv_window = 1 ;
3782
+ float window = 6 ;
3783
3783
3784
3784
float min_mod = 0 .5f ;
3785
3785
float max_mod = 1 .0f ;
3786
- float mod_pool = 1 .25f ;
3787
-
3788
- float moving_cv_init = 0 .5f ;
3789
- float roll_cv_cutoff = 0 .4f ;
3786
+ float penalty = 0 .1f ;
3790
3787
3791
3788
const vector<pair<std::string, float *>> _params{
3792
- { " itv_window " , &itv_window },
3789
+ { " window " , &window },
3793
3790
3794
3791
{ " min_mod" , &min_mod },
3795
3792
{ " max_mod" , &max_mod },
3796
- { " mod_pool" , &mod_pool },
3797
-
3798
- { " moving_cv_init" , &moving_cv_init },
3799
- { " roll_cv_cutoff" , &roll_cv_cutoff },
3793
+ { " penalty" , &penalty },
3800
3794
};
3801
3795
#pragma endregion params and param map
3802
3796
3803
- // window is currently 1 for local mod
3804
- // taps for this hand only, we don't want to include offhand taps in
3805
- // determining whether this hand is a roll
3806
- deque<int > window_itv_hand_taps;
3807
- deque<vector<int >> window_itv_rolls;
3808
-
3809
- // each element is a discrete roll formation with this many taps
3810
- // (technically it has this many taps + 4 because it requires 1212 or
3811
- // 2121 to start counting, but that's fine, that's what we want and if
3812
- // it seems better to add later we can do that
3813
- vector<int > itv_rolls;
3814
-
3815
- // unlike ccacc, which has a half baked implementation for chains of
3816
- // 122112211221, we will actually be responsible and sequence both the
3817
- // number of rolls and the notes contained therein
3818
- bool rolling = false ;
3819
- bool is_transition = false ;
3820
- int consecutive_roll_counter = 0 ;
3797
+ moving_window_interval_float _u;
3798
+ moving_window_interval_float _wot;
3799
+ moving_window_interval_float _m8;
3800
+ moving_window_interval_float _hekk;
3821
3801
3822
- int window_hand_taps = 0 ;
3823
- // for now we will be lazy and just add up the number of roll taps in any
3824
- // roll, if we leave out the initialization taps (the 4 required to identify
3825
- // the start) we will greatly reduce the effect of short roll bursts, not
3826
- // sure if this is desired behavior
3827
- int window_roll_taps = 0 ;
3828
3802
float pmod = min_mod;
3829
3803
3830
- vector<float > seq_ms = { 0 .f , 0 .f , 0 .f };
3831
- // uhhh lazy way out of tracking all the floats i think
3832
- float moving_cv = moving_cv_init;
3833
-
3834
- // non-empty (cc_type is now always non-empty)
3835
- cc_type last_seen_cc = cc_init;
3836
- cc_type last_last_seen_cc = cc_init;
3837
3804
#pragma region generic functions
3838
3805
inline void setup (vector<float > doot[], const int & size)
3839
3806
{
@@ -3866,209 +3833,61 @@ struct ChaosMod
3866
3833
}
3867
3834
#pragma endregion
3868
3835
3869
- // should rename as it resets or completes a sequence... maybe should go
3870
- // look at rm_sequencing again and make roll_sequencing.. idk
3871
- inline void reset_sequence ()
3872
- {
3873
- // only need to do this if rolling, otherwise values are false/0 anyway
3874
- if (rolling) {
3875
- itv_rolls.push_back (consecutive_roll_counter);
3876
- rolling = false ;
3877
- consecutive_roll_counter = 0 ;
3878
- }
3879
-
3880
- last_seen_cc = cc_init;
3881
- last_last_seen_cc = cc_init;
3882
- for (auto & v : seq_ms)
3883
- v = 0 .f ;
3884
- }
3885
-
3886
- // copied from wrjt, definitely needs to be tracked in metanoteinfo
3887
- inline bool detecc_ccacc (const metaHandInfo& now)
3888
- {
3889
- if (now.cc == cc_single_single)
3890
- return false ;
3891
-
3892
- if (invert_cc (now.cc ) == last_last_seen_cc)
3893
- return true ;
3894
-
3895
- return false ;
3896
- }
3897
-
3898
- // should maybe move this into metanoteinfo and do the counting there, since
3899
- // oht will need this as well, or we could be lazy and do it twice just this
3900
- // once
3901
- inline bool detecc_roll (const metaHandInfo& now)
3836
+ inline void advance_sequencing (const metaHandInfo& now)
3902
3837
{
3903
- // we allow this through up to here due to transition checks
3904
- if (now.cc == cc_single_single)
3905
- return false ;
3838
+ _u (now.cc_ms_any );
3906
3839
3907
- // if we're here the following are true, we have a full sequence of 3 cc
3908
- // taps, they are non-empty, there are no jumps and no anchors. this
3909
- // means they are all either cc_left_right, cc_right_left
3840
+ float high = _u[4 ];
3841
+ float low = now.cc_ms_any ;
3910
3842
3911
- // now we know we have cc_left_right or cc_right_left, so, xy, we are
3912
- // looking for xyx, meaning last would be the inverion of now
3913
- if (invert_cc (now.cc ) == last_seen_cc)
3914
- // now make sure that last_last is the same as now
3915
- if (now.cc == last_last_seen_cc)
3916
- // we now have 1212 or 2121
3917
- return true ;
3918
- return false ;
3919
- }
3920
-
3921
- inline bool handle_roll_timing_check ()
3922
- {
3923
- // see ccacc timing check in wrjt for explanations, it's basically the
3924
- // same but we have to invert the multiplication depending on which
3925
- // value is higher between seq_ms[0] and seq_ms[1] (easiest to dummy up
3926
- // a roll in an editor to see why)
3927
-
3928
- // multiply seq_ms[1] by 3 for the cv check, then put it back so it
3929
- // doesn't interfere with the next round
3930
- if (seq_ms[0 ] > seq_ms[1 ]) {
3931
- seq_ms[1 ] *= 3 .f ;
3932
- moving_cv = (moving_cv + cv (seq_ms)) / 2 .f ;
3933
- seq_ms[1 ] /= 3 .f ;
3934
- return moving_cv < roll_cv_cutoff;
3935
- } else {
3936
- // same thing but divide
3937
- seq_ms[1 ] /= 3 .f ;
3938
- moving_cv = (moving_cv + cv (seq_ms)) / 2 .f ;
3939
- seq_ms[1 ] *= 3 .f ;
3940
- return moving_cv < roll_cv_cutoff;
3843
+ if (high == 0 .f || low == 0 .f || high == low) {
3844
+ _wot (1 .f );
3845
+ _m8 (_wot.get_mean_of_window (window));
3846
+ return ;
3941
3847
}
3942
- }
3943
3848
3944
- inline void update_seq_ms (const metaHandInfo& now)
3945
- {
3946
- seq_ms[0 ] = seq_ms[1 ]; // last_last
3947
- seq_ms[1 ] = seq_ms[2 ]; // last
3849
+ if (low > high)
3850
+ std::swap (high, low);
3948
3851
3949
- // update now, we have no anchors, so always use cc_ms_any (although we
3950
- // want to move this to cc_ms_no_jumps when that gets implemented, since
3951
- // a separate jump inclusive mod should be made to handle those cases
3952
- seq_ms[2 ] = now.cc_ms_any ;
3953
- }
3852
+ float prop = high / low;
3853
+ int mop = static_cast <int >(prop);
3854
+ float flop = prop - static_cast <float >(mop);
3954
3855
3955
- inline void advance_sequencing (const metaHandInfo& now)
3956
- {
3957
- // do nothing for offhand taps
3958
- if (now.col == col_empty)
3959
- return ;
3856
+ if (flop == 0 .f ) {
3857
+ flop = 1 .f ;
3858
+ } else if (flop >= 0 .5f ) {
3859
+ flop = abs (flop - 1 .f ) + 1 .f ;
3960
3860
3961
- // only let these cases through, since we use invert_cc, anchors are
3962
- // screened out later, reset otherwise
3963
- if (now.cc != cc_left_right && now.cc != cc_right_left) {
3964
- reset_sequence ();
3965
- return ;
3861
+ } else if (flop < 0 .5f ) {
3862
+ flop += 1 .f ;
3966
3863
}
3967
3864
3968
- // update timing stuff
3969
- update_seq_ms (now);
3970
-
3971
- // check for a complete sequence
3972
- if (last_last_seen_cc != cc_init)
3973
- // check for rolls (cc -> inverted(cc) -> cc)
3974
- // now.mt == meta_oht (works in trill idk wtf, but it isn't working
3975
- // here?)
3976
- if (detecc_roll (now) && handle_roll_timing_check ()) {
3977
- if (rolling) {
3978
- // these should always be mutually exclusive
3979
- ++consecutive_roll_counter;
3980
- } else {
3981
- // we could increase the roll counter here, but really
3982
- // all we have now is a minitrill, so lets see if it
3983
- // extends to at least 5 notes before doing anything
3984
- rolling = true ;
3985
- }
3986
- // only reset here if this fails and a transition wasn't
3987
- // detected, if we reset here we have to assign seq_ms[2] again,
3988
- // yes this is asofgasfjasofdj messy
3989
- }
3990
-
3991
- // update sequence
3992
- last_last_seen_cc = last_seen_cc;
3993
- last_seen_cc = now.cc ;
3865
+ _wot (flop);
3866
+ _m8 (_wot.get_mean_of_window (window));
3994
3867
}
3995
3868
3996
- inline bool handle_case_optimizations (vector<float > doot[], const int & i)
3869
+ inline bool handle_case_optimizations (const ItvInfo& itvi,
3870
+ vector<float > doot[],
3871
+ const int & i)
3997
3872
{
3998
- // no taps, no rolls
3999
- if (window_hand_taps == 0 || window_roll_taps == 0 ) {
3873
+ if (itvi.total_taps == 0 ) {
4000
3874
neutral_set (_pmod, doot, i);
4001
3875
return true ;
4002
3876
}
4003
3877
4004
- // full roll
4005
- if (window_hand_taps == window_roll_taps) {
4006
- mod_set (_pmod, doot, i, min_mod);
4007
- return true ;
4008
- }
4009
-
4010
3878
return false ;
4011
3879
}
4012
3880
4013
3881
inline void operator ()(const ItvHandInfo& itvh,
4014
3882
vector<float > doot[],
4015
3883
const int & i)
4016
3884
{
4017
- neutral_set (_pmod, doot, i);
4018
- return ;
4019
-
4020
- // drop the oldest interval values if we have reached full
4021
- // size
4022
- if (window_itv_hand_taps.size () == itv_window) {
4023
- window_itv_hand_taps.pop_front ();
4024
- window_itv_rolls.pop_front ();
4025
- }
4026
-
4027
- // this is slightly hacky buuut if we have a roll that doesn't complete
4028
- // by the end of the interval, it should count for that interval, but we
4029
- // don't want the value to double up so we will reset the counter on
4030
- // interval end but _not_ reset the rolling bool, so it won't interfere
4031
- // with the detection as the sequencing passes into the next interval,
4032
- // and won't double up values
4033
- if (consecutive_roll_counter > 0 ) {
4034
- itv_rolls.push_back (consecutive_roll_counter);
4035
- consecutive_roll_counter = 0 ;
4036
- }
4037
-
4038
- window_itv_hand_taps.push_back (itvh.hand_taps );
4039
- window_itv_rolls.push_back (itv_rolls);
3885
+ _hekk (_m8.get_mean_of_window (6 ));
4040
3886
4041
- window_hand_taps = 0 ;
4042
- for (auto & n : window_itv_hand_taps)
4043
- window_hand_taps += n;
4044
-
4045
- window_roll_taps = 0 ;
4046
- // for now just add everything up
4047
- for (auto & n : window_itv_rolls)
4048
- for (auto & v : n)
4049
- window_roll_taps += v;
4050
-
4051
- if (handle_case_optimizations (doot, i)) {
4052
- interval_reset ();
4053
- return ;
4054
- }
4055
-
4056
- pmod = max_mod;
4057
- if (window_roll_taps > 0 && window_hand_taps > 0 )
4058
- pmod = mod_pool - (static_cast <float >(window_roll_taps) /
4059
- static_cast <float >(window_hand_taps));
4060
-
4061
- pmod = CalcClamp (pmod, min_mod, max_mod);
3887
+ float zmod = _hekk.get_mean_of_window (window);
3888
+ pmod = _m8.get_mean_of_window (6 ) - penalty;
4062
3889
doot[_pmod][i] = pmod;
4063
-
4064
- interval_reset ();
4065
3890
}
4066
-
4067
- // may be unneeded for this function but it's probably good practice to have
4068
- // this and always reset anything that needs to be on handling case
4069
- // optimizations, even if the case optimizations don't require us to reset
4070
- // anything
4071
- inline void interval_reset () { itv_rolls.clear (); }
4072
3891
};
4073
3892
4074
3893
struct RM_Sequencing
@@ -6265,6 +6084,7 @@ struct TheGreatBazoinkazoinkInTheSky
6265
6084
_rm.advance_sequencing (*_mhi);
6266
6085
_wrr.advance_sequencing (*_mhi);
6267
6086
_wrjt.advance_sequencing (*_mhi);
6087
+ _ch.advance_sequencing (*_mhi);
6268
6088
}
6269
6089
6270
6090
inline void setup_dependent_mods (vector<float > _doot[])
0 commit comments