1 #include <math.h>
2 #include <stdlib.h>
3 #include "soundpipe.h"
4 #include "CUI.h"
5 
6 #define max(a,b) ((a < b) ? b : a)
7 #define min(a,b) ((a < b) ? a : b)
8 
9 
10 #ifndef FAUSTFLOAT
11 #define FAUSTFLOAT SPFLOAT
12 #endif
13 
14 typedef struct {
15 	float fRec2[2];
16 	float fRec1[2];
17 	float fRec0[2];
18 	int fSamplingFreq;
19 	int iConst0;
20 	float fConst1;
21 	FAUSTFLOAT fHslider0;
22 	FAUSTFLOAT fHslider1;
23 	float fConst2;
24 	FAUSTFLOAT fHslider2;
25 	FAUSTFLOAT fHslider3;
26 } compressor;
27 
newcompressor()28 static compressor* newcompressor() {
29 	compressor* dsp = (compressor*)malloc(sizeof(compressor));
30 	return dsp;
31 }
32 
deletecompressor(compressor * dsp)33 static void deletecompressor(compressor* dsp) {
34 	free(dsp);
35 }
36 
instanceInitcompressor(compressor * dsp,int samplingFreq)37 static void instanceInitcompressor(compressor* dsp, int samplingFreq) {
38 	dsp->fSamplingFreq = samplingFreq;
39 	dsp->iConst0 = min(192000, max(1, dsp->fSamplingFreq));
40 	dsp->fConst1 = (2.f / (float)dsp->iConst0);
41 	dsp->fHslider0 = (FAUSTFLOAT)0.1;
42 	dsp->fHslider1 = (FAUSTFLOAT)1.;
43 	dsp->fConst2 = (1.f / (float)dsp->iConst0);
44 	dsp->fHslider2 = (FAUSTFLOAT)0.1;
45 	/* C99 loop */
46 	{
47 		int i0;
48 		for (i0 = 0; (i0 < 2); i0 = (i0 + 1)) {
49 			dsp->fRec2[i0] = 0.f;
50 
51 		}
52 
53 	}
54 	/* C99 loop */
55 	{
56 		int i1;
57 		for (i1 = 0; (i1 < 2); i1 = (i1 + 1)) {
58 			dsp->fRec1[i1] = 0.f;
59 
60 		}
61 
62 	}
63 	dsp->fHslider3 = (FAUSTFLOAT)0.;
64 	/* C99 loop */
65 	{
66 		int i2;
67 		for (i2 = 0; (i2 < 2); i2 = (i2 + 1)) {
68 			dsp->fRec0[i2] = 0.f;
69 
70 		}
71 
72 	}
73 
74 }
75 
initcompressor(compressor * dsp,int samplingFreq)76 static void initcompressor(compressor* dsp, int samplingFreq) {
77 	instanceInitcompressor(dsp, samplingFreq);
78 }
79 
buildUserInterfacecompressor(compressor * dsp,UIGlue * interface)80 static void buildUserInterfacecompressor(compressor* dsp, UIGlue* interface) {
81 	interface->addHorizontalSlider(interface->uiInterface, "ratio", &dsp->fHslider1, 1.f, 1.f, 40.f, 0.001f);
82 	interface->addHorizontalSlider(interface->uiInterface, "thresh", &dsp->fHslider3, 0.f, -80.f, 0.f, 0.001f);
83 	interface->addHorizontalSlider(interface->uiInterface, "atk", &dsp->fHslider0, 0.1f, 0.f, 10.f, 0.001f);
84 	interface->addHorizontalSlider(interface->uiInterface, "rel", &dsp->fHslider2, 0.1f, 0.f, 10.f, 0.001f);
85 }
86 
computecompressor(compressor * dsp,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)87 static void computecompressor(compressor* dsp, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
88 	FAUSTFLOAT* input0 = inputs[0];
89 	FAUSTFLOAT* output0 = outputs[0];
90 	float fSlow0 = (float)dsp->fHslider0;
91 	float fSlow1 = exp((0.f - (dsp->fConst1 / fSlow0)));
92 	float fSlow2 = ((1.f - fSlow1) * ((1.f / (float)dsp->fHslider1) - 1.f));
93 	float fSlow3 = exp((0.f - (dsp->fConst2 / fSlow0)));
94 	float fSlow4 = exp((0.f - (dsp->fConst2 / (float)dsp->fHslider2)));
95 	float fSlow5 = (float)dsp->fHslider3;
96 	/* C99 loop */
97 	{
98 		int i;
99 		for (i = 0; (i < count); i = (i + 1)) {
100 			float fTemp0 = (float)input0[i];
101 			float fTemp1 = fabs(fTemp0);
102 			float fTemp2 = ((dsp->fRec1[1] > fTemp1)?fSlow4:fSlow3);
103 			dsp->fRec2[0] = ((dsp->fRec2[1] * fTemp2) + ((1.f - fTemp2) * fTemp1));
104 			dsp->fRec1[0] = dsp->fRec2[0];
105 			dsp->fRec0[0] = ((fSlow1 * dsp->fRec0[1]) + (fSlow2 * max(((20.f * log10(dsp->fRec1[0])) - fSlow5), 0.f)));
106 			output0[i] = (FAUSTFLOAT)(pow(10.f, (0.05f * dsp->fRec0[0])) * fTemp0);
107 			dsp->fRec2[1] = dsp->fRec2[0];
108 			dsp->fRec1[1] = dsp->fRec1[0];
109 			dsp->fRec0[1] = dsp->fRec0[0];
110 
111 		}
112 
113 	}
114 
115 }
116 
addHorizontalSlider(void * ui_interface,const char * label,FAUSTFLOAT * zone,FAUSTFLOAT init,FAUSTFLOAT min,FAUSTFLOAT max,FAUSTFLOAT step)117 static void addHorizontalSlider(void* ui_interface, const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
118 {
119     sp_compressor *p = ui_interface;
120     p->args[p->argpos] = zone;
121     p->argpos++;
122 }
123 
sp_compressor_create(sp_compressor ** p)124 int sp_compressor_create(sp_compressor **p)
125 {
126     *p = malloc(sizeof(sp_compressor));
127     return SP_OK;
128 }
129 
sp_compressor_destroy(sp_compressor ** p)130 int sp_compressor_destroy(sp_compressor **p)
131 {
132     sp_compressor *pp = *p;
133     compressor *dsp = pp->faust;
134     deletecompressor (dsp);
135     free(*p);
136     return SP_OK;
137 }
138 
sp_compressor_init(sp_data * sp,sp_compressor * p)139 int sp_compressor_init(sp_data *sp, sp_compressor *p)
140 {
141     compressor *dsp = newcompressor();
142     UIGlue UI;
143     p->argpos = 0;
144     UI.addHorizontalSlider= addHorizontalSlider;
145     UI.uiInterface = p;
146     buildUserInterfacecompressor(dsp, &UI);
147     initcompressor(dsp, sp->sr);
148 
149 
150     p->ratio = p->args[0];
151     p->thresh = p->args[1];
152     p->atk = p->args[2];
153     p->rel = p->args[3];
154 
155     p->faust = dsp;
156     return SP_OK;
157 }
158 
sp_compressor_compute(sp_data * sp,sp_compressor * p,SPFLOAT * in,SPFLOAT * out)159 int sp_compressor_compute(sp_data *sp, sp_compressor *p, SPFLOAT *in, SPFLOAT *out)
160 {
161 
162     compressor *dsp = p->faust;
163     SPFLOAT *faust_out[] = {out};
164     SPFLOAT *faust_in[] = {in};
165     computecompressor(dsp, 1, faust_in, faust_out);
166     return SP_OK;
167 }
168