/
highest~.c
95 lines (82 loc) · 2.56 KB
/
highest~.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
#include "shadylib.h"
#define MAXPRD 4194304
static t_class *highest_tilde_class;
typedef struct _highest
{
t_object x_obj;
t_outlet *x_outlet; /* a "float" outlet */
void *x_clock; /* a "clock" object */
t_sample x_result;
t_float x_f;
int x_period;
int x_blocksize;
int x_realperiod;
int x_count;
} t_highest;
static void highest_set(t_highest *x, t_float nsamps) {
x->x_result = 0.f;
x->x_count = 0;
if(nsamps != 0.f) {
int isamps = shadylib_min(shadylib_pdfloat_abs(nsamps), MAXPRD);
int n = x->x_blocksize;
x->x_period = isamps;
/* get next multiple of n */
x->x_realperiod = isamps+(n-1) - ((isamps+(n-1))&(n-1));
}
}
static void highest_tilde_tick(t_highest *x) {
outlet_float(x->x_outlet, x->x_result);
x->x_result = 0;
}
static void highest_tilde_free(t_highest *x) /* cleanup on free */
{
clock_free(x->x_clock);
}
static void *highest_tilde_new(t_floatarg nsamps) {
t_highest *x = (t_highest *)pd_new(highest_tilde_class);
x->x_outlet = outlet_new(&x->x_obj, &s_float);
x->x_clock = clock_new(x, (t_method)highest_tilde_tick);
x->x_blocksize = 64;
if(!nsamps) x->x_period = 1024;
else highest_set(x , nsamps);
x->x_f = 0.f;
return (x);
}
static t_int *highest_tilde_perform(t_int *w) {
t_highest *x = (t_highest *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample result = x->x_result, temp;
x->x_count += n;
if(x->x_count >= x->x_realperiod) {
x->x_count = 0;
clock_delay(x->x_clock, 0.0);
}
while(n--) {
temp = shadylib_pdfloat_abs(*in);
if(result < temp) result = temp;
in++;
}
x->x_result = result;
return (w+4);
}
static void highest_tilde_dsp(t_highest *x, t_signal **sp)
{
/* assume n is a power of 2 */
int n = sp[0]->s_n;
x->x_blocksize = n;
/* get next multiple of n */
x->x_realperiod = x->x_period+(n-1) - ((x->x_period+(n-1))&(n-1));
x->x_count = 0;
dsp_add(highest_tilde_perform, 3, x, sp[0]->s_vec, n);
}
void highest_tilde_setup(void)
{
highest_tilde_class = class_new(gensym("highest~"), (t_newmethod)highest_tilde_new, (t_method)highest_tilde_free,
sizeof(t_highest), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(highest_tilde_class, t_highest, x_f);
class_addmethod(highest_tilde_class, (t_method)highest_tilde_dsp,
gensym("dsp"), A_CANT, 0);
class_addmethod(highest_tilde_class, (t_method)highest_set,
gensym("set"), A_FLOAT, 0);
}