-
Notifications
You must be signed in to change notification settings - Fork 2
/
wrEvent.c
160 lines (143 loc) · 4.31 KB
/
wrEvent.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "wrEvent.h"
#include <stdio.h>
event_extract_t* Extract_init( void )
{
event_extract_t* e = malloc(sizeof(event_extract_t));
if( !e ){ printf("Event malloc failed\n"); return NULL; }
// parameter defaults
e->hyst_time = 10; // >= EXTRACT_HIST_LENGTH for debouncing
// these constants are divided by EXTRACT_HIST_LENGTH
// trigger detection
e->tr_abs_level = 0.25; // trigger level re:0v
e->tr_rel_level = 0.2; // trigger level re:cv-level
// trigger||cv thresholds
e->cv_thresh_same = 0.2; // cv-level re:0v (same dir as trigger)
e->cv_thresh_opp = 0.15; // cv-level re:0v (opposite dir)
// state
e->hyst = 0;
for( uint8_t i=0; i<EXTRACT_HIST_LENGTH; i++ ){
e->in_history[i] = 0.0;
}
e->gate_state = 0;
return e;
}
void Extract_deinit( event_extract_t* e )
{
free(e); e = NULL;
}
etrig_t Extract_cv_trigger( event_extract_t* e, float in )
{
etrig_t retval = tr_none;
if( e->hyst == 0 ){
if( e->gate_state == 0 ){
if( in > (e->in_history[0] + e->tr_rel_level)
&& in >= e->tr_abs_level ){
// trigger high
// replace these conditionals with some integer math
// shift the cv, scale, then cast, then lookup in tr_t
if( e->in_history[0] > e->cv_thresh_same ){
retval = tr_p_positive;
} else if( e->in_history[0] < -(e->cv_thresh_opp) ){
retval = tr_p_negative;
} else {
retval = tr_p_same;
}
e->gate_state = 1;
e->hyst = e->hyst_time;
} else if( in < (e->in_history[0] - e->tr_rel_level)
&& in <= -(e->tr_abs_level) ){
// trigger low
if( e->in_history[0] > e->cv_thresh_opp ){
retval = tr_n_positive;
} else if( e->in_history[0] < -(e->cv_thresh_same) ){
retval = tr_n_negative;
} else {
retval = tr_n_same;
}
e->gate_state = -1;
e->hyst = e->hyst_time;
} else {
// no trigger -> gate-state unchanged
retval = tr_none;
}
} else { // gate_state is HIGH
if( in < e->tr_abs_level
&& in > -(e->tr_abs_level) ){
retval = tr_none;
e->gate_state = 0; // release
e->hyst = e->hyst_time;
} else {
retval = tr_hold; // still holding!
}
}
} else {
e->hyst--; if( e->hyst < 0 ){ e->hyst = 0; }
retval = tr_hold;
}
// circular buffer
for( uint8_t i=0; i<EXTRACT_HIST_LENGTH - 1; i++ ){
e->in_history[i] = e->in_history[i+1];
} e->in_history[EXTRACT_HIST_LENGTH - 1] = in;
return retval;
}
Debounce_t* Debounce_init( uint16_t debounce_count )
{
Debounce_t* db = malloc( sizeof( Debounce_t ) );
if( !db ){ printf("Debounce malloc failed\n"); return NULL; }
db->state = 0;
db->count = 0;
db->count_to = debounce_count;
return db;
}
void Debounce_deinit( Debounce_t* db )
{
free(db); db = NULL;
}
uint8_t Debounce_step( Debounce_t* db, uint8_t in )
{
if( in != db->state ){ // change
if( ++db->count >= db->count_to ){
db->state = in;
db->count = 0;
}
} else {
db->count = 0;
}
return db->state;
}
// should inherit from debounce
Debounce_a_t* Debounce_a_init( uint16_t debounce_count_up
, uint16_t debounce_count_down
)
{
Debounce_a_t* db = malloc( sizeof( Debounce_a_t ) );
if( !db ){ printf("Debounce_a malloc failed\n"); return NULL; }
db->state = 0;
db->count = 0;
db->count_to_up = debounce_count_up;
db->count_to_down = debounce_count_down;
return db;
}
void Debounce_a_deinit( Debounce_a_t* db )
{
free(db); db = NULL;
}
uint8_t Debounce_a_step( Debounce_a_t* db, uint8_t in )
{
if( in != db->state ){ // change
if( db->state ){
if( ++db->count >= db->count_to_down ){
db->state = in;
db->count = 0;
}
} else {
if( ++db->count >= db->count_to_up ){
db->state = in;
db->count = 0;
}
}
} else {
db->count = 0;
}
return db->state;
}