Skip to content

Commit 10cb0fc

Browse files
committed
add c code
1 parent 2b3aabe commit 10cb0fc

File tree

2 files changed

+308
-0
lines changed

2 files changed

+308
-0
lines changed

build/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
set(CMAKE_OSX_ARCHITECTURES x86_64;arm64)
2+
3+
include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake)
4+
5+
#############################################################
6+
# MAX EXTERNAL
7+
#############################################################
8+
9+
include_directories(
10+
"${MAX_SDK_INCLUDES}"
11+
"${MAX_SDK_MSP_INCLUDES}"
12+
"${MAX_SDK_JIT_INCLUDES}"
13+
)
14+
15+
file(GLOB PROJECT_SRC
16+
"*.h"
17+
"*.c"
18+
"*.cpp"
19+
)
20+
add_library(
21+
${PROJECT_NAME}
22+
MODULE
23+
${PROJECT_SRC}
24+
)
25+
26+
include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake)

build/mookVCF~.c

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
//
2+
// mookVCF.cpp
3+
// max-external
4+
//
5+
// Created by Nicolas Brochec on 25/07/2022.
6+
//
7+
8+
#include "ext.h"
9+
#include "ext_obex.h"
10+
#include "z_dsp.h"
11+
#include <math.h>
12+
13+
static t_class *mookVCF_class; // création de la classe
14+
15+
16+
typedef struct _mookVCF
17+
{
18+
t_pxobject s_ob;
19+
double s_freq;
20+
double s_res;
21+
double s_fqterm;
22+
double s_p, s_k, s_ym1, s_ym2, s_ym3, s_ym4, s_lp, s_lk;
23+
double s_lx, s_ly1, s_ly2, s_ly3;
24+
double s_resterm;
25+
double s_t1, s_t2;
26+
double connected;
27+
double s_fcon;
28+
double s_rcon;
29+
double s_sr;
30+
31+
}t_mookVCF;
32+
33+
void mookVCF_float(t_mookVCF *x, double f);
34+
void mookVCF_int(t_mookVCF *x, long n);
35+
void mookVCF_free(t_mookVCF *x);
36+
void mookVCF_clear(t_mookVCF *x);
37+
void mookVCF_calc(t_mookVCF *x);
38+
void mookVCF_dsp64(t_mookVCF *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags);
39+
void mookVCF_perform64(t_mookVCF *x,t_object *dsp64,double **ins,long numins,double **outs,long numouts,long sampleframes, long flags,void *userparam);
40+
t_max_err mookVCF_attr_setcutoff(t_mookVCF *x, void *attr, long argc, t_atom *argv);
41+
t_max_err mookVCF_attr_setresonance(t_mookVCF *x, void *attr, long argc, t_atom *argv);
42+
void mookVCF_assist(t_mookVCF *x, void *b, long m, long a, char *s);
43+
void *mookVCF_new(t_symbol *s, long argc, t_atom *argv);
44+
45+
// エクスターナル構造
46+
C74_EXPORT void ext_main(void *r){
47+
t_class *c;
48+
c = class_new("mookVCF~", (method)mookVCF_new, (method)dsp_free, (long)sizeof(t_mookVCF),0L,A_GIMME,0);
49+
class_addmethod(c,(method)mookVCF_float,"float", A_FLOAT,0);
50+
class_addmethod(c,(method)mookVCF_int,"int", A_LONG, 0);
51+
class_addmethod(c,(method)mookVCF_dsp64,"dsp64", A_CANT, 0);
52+
class_addmethod(c,(method)mookVCF_clear, "clear", 0);
53+
class_addmethod(c,(method)mookVCF_assist, "assist", A_CANT, 0);
54+
55+
CLASS_ATTR_DOUBLE(c, "cutoff",0, t_mookVCF, s_freq);
56+
CLASS_ATTR_BASIC(c, "cutoff", 0);
57+
CLASS_ATTR_LABEL(c, "cutoff", 0, "Cutoff Frequency");
58+
// CLASS_ATTR_STYLE_LABEL(c, "cutoff", 0, "Cutoff Frequency", "Cutoff Frequency");
59+
CLASS_ATTR_ALIAS(c, "cutoff", "freq");
60+
CLASS_ATTR_ACCESSORS(c, "cutoff", 0, mookVCF_attr_setcutoff);
61+
62+
CLASS_ATTR_DOUBLE(c, "resonance", 0, t_mookVCF, s_res);
63+
CLASS_ATTR_BASIC(c, "resonance", 0);
64+
CLASS_ATTR_LABEL(c, "resonance", 0, "Resonance");
65+
// CLASS_ATTR_STYLE_LABEL(c, "resonance", 0, "Resonance", "Resonance");
66+
CLASS_ATTR_ALIAS(c, "resonance", "q");
67+
CLASS_ATTR_ACCESSORS(c, "resonance", 0, mookVCF_attr_setresonance);
68+
class_dspinit(c);
69+
70+
class_register(CLASS_BOX,c);
71+
mookVCF_class=c;
72+
73+
}
74+
void mookVCF_free(t_mookVCF *x)
75+
{
76+
;
77+
}
78+
79+
void mookVCF_dsp64(t_mookVCF *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags){
80+
81+
x->s_sr = samplerate;
82+
mookVCF_clear(x);
83+
x->s_lp = x->s_p;
84+
x->s_lk = x->s_k;
85+
x->s_fcon = count[1];
86+
x->s_rcon = count[2];
87+
mookVCF_calc(x);
88+
object_method(dsp64, gensym("dsp_add64"), x, mookVCF_perform64, 0, NULL);
89+
}
90+
91+
void mookVCF_int(t_mookVCF *x, long n){
92+
mookVCF_float(x, (double)n);
93+
}
94+
95+
void mookVCF_float(t_mookVCF *x, double f){
96+
97+
long in = proxy_getinlet((t_object *)x);
98+
99+
if(in==1){
100+
x->s_freq= f < 1. ? 1 : f;
101+
x->s_freq=f;
102+
object_attr_touch((t_object *)x, gensym("cutoff"));
103+
mookVCF_calc(x);
104+
}else if(in==2){
105+
if(f >= 1){
106+
f = 1.f - 1E-20;
107+
x->s_res = f;
108+
}else if(f<0.){
109+
f = 0.f;
110+
x->s_res = f;
111+
}else{
112+
x->s_res = f;
113+
}
114+
115+
object_attr_touch((t_object *)x, gensym("resonance"));
116+
mookVCF_calc(x);
117+
}
118+
}
119+
120+
t_max_err mookVCF_attr_setcutoff(t_mookVCF *x, void *attr, long argc, t_atom *argv){
121+
double freq = atom_getfloat(argv);
122+
123+
x->s_freq = freq < 1. ? 1 : freq;
124+
mookVCF_calc(x);
125+
return 0.;
126+
}
127+
128+
t_max_err mookVCF_attr_setresonance(t_mookVCF *x, void *attr, long argc, t_atom *argv){
129+
double reso = atom_getfloat(argv);
130+
131+
if(reso >= 1){
132+
reso = 1.f - 1E-20;
133+
// reso = 0.98;
134+
x->s_res = reso;
135+
}else if(reso<0.){
136+
reso = 0.f;
137+
x->s_res = reso;
138+
}else{
139+
x->s_res = reso;
140+
}
141+
142+
mookVCF_calc(x);
143+
return 0;
144+
}
145+
146+
void mookVCF_perform64(t_mookVCF *x,t_object *dsp64,double **ins,long numins,double **outs,long numouts,long sampleframes,long flags,void *userparam){
147+
148+
t_double *in1=ins[0];
149+
t_double *out=outs[0];
150+
t_double freq = x->s_fcon ? *ins[1] : x->s_freq; // vérifier s'il y a du signal dans les entrées 2 et 3
151+
t_double res = x->s_res ? *ins[2] : x->s_res;
152+
153+
double X;
154+
double y1=x->s_ym1;
155+
double y2=x->s_ym2;
156+
double y3=x->s_ym3;
157+
double y4=x->s_ym4;
158+
double k = x->s_k;
159+
double p = x->s_p;
160+
double resterm = x->s_resterm;
161+
double t1 = x->s_t1;
162+
double t2 = x->s_t2;
163+
164+
// scale resonance
165+
if(res >= 1){
166+
res = 1.f - 1E-20;
167+
}else if(res<0.){
168+
res = 0.f;
169+
}
170+
171+
// do we need to calculate the coefs ?
172+
if(freq != x->s_freq || res != x->s_res){
173+
if(res != x->s_res){
174+
resterm = x->s_resterm = x->s_res * (t2+6.f*t1) / (t2-6.f*t1);
175+
}else{
176+
resterm = x->s_resterm;
177+
}
178+
if(freq !=x->s_freq){
179+
x->s_fqterm = (x->s_freq + x->s_freq) / x->s_sr;
180+
x->s_p = p = x->s_fqterm * (1.0f - 0.8f * x->s_fqterm);
181+
x->s_k = k = p + p - 1.f;
182+
x->s_t1 = (1.f - p) * 1.386249;
183+
t1 = x->s_t1;
184+
x->s_t2 = 12.f + t1 * t1;
185+
t2 = x->s_t2;
186+
}
187+
}
188+
189+
190+
while(sampleframes--){
191+
192+
X = *in1++ - resterm * y4;
193+
y1 = X * p + x->s_lx * p - k * y1;
194+
y2 = y1 * p + x->s_ly1 * p - k * y2;
195+
y3 = y2 * p + x->s_ly2 * p - k * y3;
196+
y4 = y3 * p + x->s_ly3 * p - k * y4;
197+
198+
y4 -= (y4*y4*y4) / 6.f;
199+
200+
*out++=y4;
201+
x->s_lx = X; x->s_ly1 = y1; x->s_ly2 = y2; x->s_ly3 = y3;
202+
203+
}
204+
205+
x->s_ym1=y1; x->s_ym2=y2; x->s_ym3=y3; x->s_ym4=y4;
206+
207+
}
208+
209+
void mookVCF_clear(t_mookVCF *x){
210+
x->s_ym1=x->s_ym2=x->s_ym3=x->s_ym4=0.;
211+
x->s_p=x->s_k=x->s_lp=x->s_lk=0.;
212+
x->s_lx=x->s_ly1=x->s_ly2=x->s_ly3=0.;
213+
}
214+
215+
void mookVCF_assist(t_mookVCF *x, void *b, long m, long a, char *s)
216+
{
217+
if(m==2){
218+
sprintf(s, "(signal) Output");
219+
}else{
220+
switch (a) {
221+
case 0: sprintf(s, "(signal) Input"); break;
222+
case 1: sprintf(s, "(signal/float) Cutoff Frequency"); break;
223+
case 2: sprintf(s, "(signal/float) Resonance Control (0-1)"); break;
224+
}
225+
}
226+
}
227+
228+
void mookVCF_calc(t_mookVCF *x){
229+
230+
x->s_fqterm = (x->s_freq + x->s_freq) / x->s_sr;
231+
x->s_p = x->s_fqterm * (1.0f - 0.8f * x->s_fqterm);
232+
x->s_k = x->s_p + x->s_p - 1.f;
233+
x->s_t1 = (1.f - x->s_p) * 1.386249;
234+
x->s_t2 = 12.f + x->s_t1 * x->s_t1 ;
235+
x->s_resterm = x->s_res * (x->s_t2+6.f* x->s_t1) / (x->s_t2-6.f* x->s_t1);
236+
237+
}
238+
239+
void *mookVCF_new(t_symbol *s, long argc, t_atom *argv){
240+
t_mookVCF *x = object_alloc(mookVCF_class);
241+
242+
double freq, reso, offset;
243+
offset = attr_args_offset((short)argc, argv);
244+
dsp_setup((t_pxobject *)x, 3);
245+
246+
if (offset) {
247+
freq = atom_getlong(argv);
248+
if ((argv)->a_type == A_LONG){
249+
object_post((t_object*)x, "arg[%ld] Cutoff Frequency: %ld", 0, atom_getlong(argv));
250+
}
251+
if (offset > 1){
252+
reso = atom_getfloat(argv + 1);
253+
if ((argv + 1)->a_type == A_FLOAT){
254+
object_post((t_object*)x, "arg[%ld] Resonance: %f", 1, atom_getfloat(argv+1));
255+
}
256+
}
257+
}
258+
259+
x->s_freq = freq < 1. ? 1 : freq;
260+
261+
if(reso >= 1){
262+
reso = 1.f - 1E-20;
263+
x->s_res = reso;
264+
}else if(reso<0.){
265+
reso = 0.f;
266+
x->s_res = reso;
267+
}else{
268+
x->s_res = reso;
269+
}
270+
271+
attr_args_process(x, (short)argc, argv);
272+
273+
x->s_sr = sys_getsr();
274+
x->s_lp = x->s_p;
275+
x->s_lk = x->s_k;
276+
277+
mookVCF_calc(x);
278+
outlet_new((t_pxobject*)x,"signal");
279+
return x;
280+
}
281+
282+

0 commit comments

Comments
 (0)