1 /* ========================================
2  *  DrumSlam - DrumSlam.h
3  *  Copyright (c) 2016 airwindows, All rights reserved
4  * ======================================== */
5 
6 #ifndef __DrumSlam_H
7 #include "DrumSlam.h"
8 #endif
9 
10 namespace DrumSlam {
11 
12 
processReplacing(float ** inputs,float ** outputs,VstInt32 sampleFrames)13 void DrumSlam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
14 {
15     float* in1  =  inputs[0];
16     float* in2  =  inputs[1];
17     float* out1 = outputs[0];
18     float* out2 = outputs[1];
19 
20 	double overallscale = 1.0;
21 	overallscale /= 44100.0;
22 	overallscale *= getSampleRate();
23 	double iirAmountL = 0.0819;
24 	iirAmountL /= overallscale;
25 	double iirAmountH = 0.377933067;
26 	iirAmountH /= overallscale;
27 	double drive = (A*3.0)+1.0;
28 	double out = B;
29 	double wet = C;
30 	double dry = 1.0 - wet;
31 
32     while (--sampleFrames >= 0)
33     {
34 		long double inputSampleL = *in1;
35 		long double inputSampleR = *in2;
36 		if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
37 			static int noisesource = 0;
38 			//this declares a variable before anything else is compiled. It won't keep assigning
39 			//it to 0 for every sample, it's as if the declaration doesn't exist in this context,
40 			//but it lets me add this denormalization fix in a single place rather than updating
41 			//it in three different locations. The variable isn't thread-safe but this is only
42 			//a random seed and we can share it with whatever.
43 			noisesource = noisesource % 1700021; noisesource++;
44 			int residue = noisesource * noisesource;
45 			residue = residue % 170003; residue *= residue;
46 			residue = residue % 17011; residue *= residue;
47 			residue = residue % 1709; residue *= residue;
48 			residue = residue % 173; residue *= residue;
49 			residue = residue % 17;
50 			double applyresidue = residue;
51 			applyresidue *= 0.00000001;
52 			applyresidue *= 0.00000001;
53 			inputSampleL = applyresidue;
54 		}
55 		if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
56 			static int noisesource = 0;
57 			noisesource = noisesource % 1700021; noisesource++;
58 			int residue = noisesource * noisesource;
59 			residue = residue % 170003; residue *= residue;
60 			residue = residue % 17011; residue *= residue;
61 			residue = residue % 1709; residue *= residue;
62 			residue = residue % 173; residue *= residue;
63 			residue = residue % 17;
64 			double applyresidue = residue;
65 			applyresidue *= 0.00000001;
66 			applyresidue *= 0.00000001;
67 			inputSampleR = applyresidue;
68 			//this denormalization routine produces a white noise at -300 dB which the noise
69 			//shaping will interact with to produce a bipolar output, but the noise is actually
70 			//all positive. That should stop any variables from going denormal, and the routine
71 			//only kicks in if digital black is input. As a final touch, if you save to 24-bit
72 			//the silence will return to being digital black again.
73 		}
74 		long double drySampleL = inputSampleL;
75 		long double drySampleR = inputSampleR;
76 		long double lowSampleL;
77 		long double lowSampleR;
78 		long double midSampleL;
79 		long double midSampleR;
80 		long double highSampleL;
81 		long double highSampleR;
82 
83 
84 		inputSampleL *= drive;
85 		inputSampleR *= drive;
86 
87 		if (fpFlip)
88 		{
89 			iirSampleAL = (iirSampleAL * (1 - iirAmountL)) + (inputSampleL * iirAmountL);
90 			iirSampleBL = (iirSampleBL * (1 - iirAmountL)) + (iirSampleAL * iirAmountL);
91 			lowSampleL = iirSampleBL;
92 
93 			iirSampleAR = (iirSampleAR * (1 - iirAmountL)) + (inputSampleR * iirAmountL);
94 			iirSampleBR = (iirSampleBR * (1 - iirAmountL)) + (iirSampleAR * iirAmountL);
95 			lowSampleR = iirSampleBR;
96 
97 			iirSampleEL = (iirSampleEL * (1 - iirAmountH)) + (inputSampleL * iirAmountH);
98 			iirSampleFL = (iirSampleFL * (1 - iirAmountH)) + (iirSampleEL * iirAmountH);
99 			midSampleL = iirSampleFL - iirSampleBL;
100 
101 			iirSampleER = (iirSampleER * (1 - iirAmountH)) + (inputSampleR * iirAmountH);
102 			iirSampleFR = (iirSampleFR * (1 - iirAmountH)) + (iirSampleER * iirAmountH);
103 			midSampleR = iirSampleFR - iirSampleBR;
104 
105 			highSampleL = inputSampleL - iirSampleFL;
106 			highSampleR = inputSampleR - iirSampleFR;
107 		}
108 		else
109 		{
110 			iirSampleCL = (iirSampleCL * (1 - iirAmountL)) + (inputSampleL * iirAmountL);
111 			iirSampleDL = (iirSampleDL * (1 - iirAmountL)) + (iirSampleCL * iirAmountL);
112 			lowSampleL = iirSampleDL;
113 
114 			iirSampleCR = (iirSampleCR * (1 - iirAmountL)) + (inputSampleR * iirAmountL);
115 			iirSampleDR = (iirSampleDR * (1 - iirAmountL)) + (iirSampleCR * iirAmountL);
116 			lowSampleR = iirSampleDR;
117 
118 			iirSampleGL = (iirSampleGL * (1 - iirAmountH)) + (inputSampleL * iirAmountH);
119 			iirSampleHL = (iirSampleHL * (1 - iirAmountH)) + (iirSampleGL * iirAmountH);
120 			midSampleL = iirSampleHL - iirSampleDL;
121 
122 			iirSampleGR = (iirSampleGR * (1 - iirAmountH)) + (inputSampleR * iirAmountH);
123 			iirSampleHR = (iirSampleHR * (1 - iirAmountH)) + (iirSampleGR * iirAmountH);
124 			midSampleR = iirSampleHR - iirSampleDR;
125 
126 			highSampleL = inputSampleL - iirSampleHL;
127 			highSampleR = inputSampleR - iirSampleHR;
128 		}
129 		fpFlip = !fpFlip;
130 
131 		//generate the tone bands we're using
132 		if (lowSampleL > 1.0) {lowSampleL = 1.0;}
133 		if (lowSampleL < -1.0) {lowSampleL = -1.0;}
134 		if (lowSampleR > 1.0) {lowSampleR = 1.0;}
135 		if (lowSampleR < -1.0) {lowSampleR = -1.0;}
136 		lowSampleL -= (lowSampleL * (fabs(lowSampleL) * 0.448) * (fabs(lowSampleL) * 0.448) );
137 		lowSampleR -= (lowSampleR * (fabs(lowSampleR) * 0.448) * (fabs(lowSampleR) * 0.448) );
138 		lowSampleL *= drive;
139 		lowSampleR *= drive;
140 
141 		if (highSampleL > 1.0) {highSampleL = 1.0;}
142 		if (highSampleL < -1.0) {highSampleL = -1.0;}
143 		if (highSampleR > 1.0) {highSampleR = 1.0;}
144 		if (highSampleR < -1.0) {highSampleR = -1.0;}
145 		highSampleL -= (highSampleL * (fabs(highSampleL) * 0.599) * (fabs(highSampleL) * 0.599) );
146 		highSampleR -= (highSampleR * (fabs(highSampleR) * 0.599) * (fabs(highSampleR) * 0.599) );
147 		highSampleL *= drive;
148 		highSampleR *= drive;
149 
150 		midSampleL = midSampleL * drive;
151 		midSampleR = midSampleR * drive;
152 
153 		long double skew = (midSampleL - lastSampleL);
154 		lastSampleL = midSampleL;
155 		//skew will be direction/angle
156 		long double bridgerectifier = fabs(skew);
157 		if (bridgerectifier > 3.1415926) bridgerectifier = 3.1415926;
158 		//for skew we want it to go to zero effect again, so we use full range of the sine
159 		bridgerectifier = sin(bridgerectifier);
160 		if (skew > 0) skew = bridgerectifier*3.1415926;
161 		else skew = -bridgerectifier*3.1415926;
162 		//skew is now sined and clamped and then re-amplified again
163 		skew *= midSampleL;
164 		//cools off sparkliness and crossover distortion
165 		skew *= 1.557079633;
166 		//crank up the gain on this so we can make it sing
167 		bridgerectifier = fabs(midSampleL);
168 		bridgerectifier += skew;
169 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
170 		bridgerectifier = sin(bridgerectifier);
171 		bridgerectifier *= drive;
172 		bridgerectifier += skew;
173 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
174 		bridgerectifier = sin(bridgerectifier);
175 		if (midSampleL > 0)
176 		{
177 			midSampleL = bridgerectifier;
178 		}
179 		else
180 		{
181 			midSampleL = -bridgerectifier;
182 		}
183 		//blend according to positive and negative controls, left
184 
185 		skew = (midSampleR - lastSampleR);
186 		lastSampleR = midSampleR;
187 		//skew will be direction/angle
188 		bridgerectifier = fabs(skew);
189 		if (bridgerectifier > 3.1415926) bridgerectifier = 3.1415926;
190 		//for skew we want it to go to zero effect again, so we use full range of the sine
191 		bridgerectifier = sin(bridgerectifier);
192 		if (skew > 0) skew = bridgerectifier*3.1415926;
193 		else skew = -bridgerectifier*3.1415926;
194 		//skew is now sined and clamped and then re-amplified again
195 		skew *= midSampleR;
196 		//cools off sparkliness and crossover distortion
197 		skew *= 1.557079633;
198 		//crank up the gain on this so we can make it sing
199 		bridgerectifier = fabs(midSampleR);
200 		bridgerectifier += skew;
201 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
202 		bridgerectifier = sin(bridgerectifier);
203 		bridgerectifier *= drive;
204 		bridgerectifier += skew;
205 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
206 		bridgerectifier = sin(bridgerectifier);
207 		if (midSampleR > 0)
208 		{
209 			midSampleR = bridgerectifier;
210 		}
211 		else
212 		{
213 			midSampleR = -bridgerectifier;
214 		}
215 		//blend according to positive and negative controls, right
216 
217 		inputSampleL = ((lowSampleL + midSampleL + highSampleL)/drive)*out;
218 		inputSampleR = ((lowSampleR + midSampleR + highSampleR)/drive)*out;
219 
220 		if (wet !=1.0) {
221 			inputSampleL = (inputSampleL * wet) + (drySampleL * dry);
222 			inputSampleR = (inputSampleR * wet) + (drySampleR * dry);
223 		}
224 
225 		//stereo 32 bit dither, made small and tidy.
226 		int expon; frexpf((float)inputSampleL, &expon);
227 		long double dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62);
228 		inputSampleL += (dither-fpNShapeL); fpNShapeL = dither;
229 		frexpf((float)inputSampleR, &expon);
230 		dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62);
231 		inputSampleR += (dither-fpNShapeR); fpNShapeR = dither;
232 		//end 32 bit dither
233 
234 		*out1 = inputSampleL;
235 		*out2 = inputSampleR;
236 
237 		in1++;
238 		in2++;
239 		out1++;
240 		out2++;
241     }
242 }
243 
processDoubleReplacing(double ** inputs,double ** outputs,VstInt32 sampleFrames)244 void DrumSlam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames)
245 {
246     double* in1  =  inputs[0];
247     double* in2  =  inputs[1];
248     double* out1 = outputs[0];
249     double* out2 = outputs[1];
250 
251 	double overallscale = 1.0;
252 	overallscale /= 44100.0;
253 	overallscale *= getSampleRate();
254 	double iirAmountL = 0.0819;
255 	iirAmountL /= overallscale;
256 	double iirAmountH = 0.377933067;
257 	iirAmountH /= overallscale;
258 	double drive = (A*3.0)+1.0;
259 	double out = B;
260 	double wet = C;
261 	double dry = 1.0 - wet;
262 
263     while (--sampleFrames >= 0)
264     {
265 		long double inputSampleL = *in1;
266 		long double inputSampleR = *in2;
267 		if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
268 			static int noisesource = 0;
269 			//this declares a variable before anything else is compiled. It won't keep assigning
270 			//it to 0 for every sample, it's as if the declaration doesn't exist in this context,
271 			//but it lets me add this denormalization fix in a single place rather than updating
272 			//it in three different locations. The variable isn't thread-safe but this is only
273 			//a random seed and we can share it with whatever.
274 			noisesource = noisesource % 1700021; noisesource++;
275 			int residue = noisesource * noisesource;
276 			residue = residue % 170003; residue *= residue;
277 			residue = residue % 17011; residue *= residue;
278 			residue = residue % 1709; residue *= residue;
279 			residue = residue % 173; residue *= residue;
280 			residue = residue % 17;
281 			double applyresidue = residue;
282 			applyresidue *= 0.00000001;
283 			applyresidue *= 0.00000001;
284 			inputSampleL = applyresidue;
285 		}
286 		if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
287 			static int noisesource = 0;
288 			noisesource = noisesource % 1700021; noisesource++;
289 			int residue = noisesource * noisesource;
290 			residue = residue % 170003; residue *= residue;
291 			residue = residue % 17011; residue *= residue;
292 			residue = residue % 1709; residue *= residue;
293 			residue = residue % 173; residue *= residue;
294 			residue = residue % 17;
295 			double applyresidue = residue;
296 			applyresidue *= 0.00000001;
297 			applyresidue *= 0.00000001;
298 			inputSampleR = applyresidue;
299 			//this denormalization routine produces a white noise at -300 dB which the noise
300 			//shaping will interact with to produce a bipolar output, but the noise is actually
301 			//all positive. That should stop any variables from going denormal, and the routine
302 			//only kicks in if digital black is input. As a final touch, if you save to 24-bit
303 			//the silence will return to being digital black again.
304 		}
305 		long double drySampleL = inputSampleL;
306 		long double drySampleR = inputSampleR;
307 		long double lowSampleL;
308 		long double lowSampleR;
309 		long double midSampleL;
310 		long double midSampleR;
311 		long double highSampleL;
312 		long double highSampleR;
313 
314 
315 		inputSampleL *= drive;
316 		inputSampleR *= drive;
317 
318 		if (fpFlip)
319 		{
320 			iirSampleAL = (iirSampleAL * (1 - iirAmountL)) + (inputSampleL * iirAmountL);
321 			iirSampleBL = (iirSampleBL * (1 - iirAmountL)) + (iirSampleAL * iirAmountL);
322 			lowSampleL = iirSampleBL;
323 
324 			iirSampleAR = (iirSampleAR * (1 - iirAmountL)) + (inputSampleR * iirAmountL);
325 			iirSampleBR = (iirSampleBR * (1 - iirAmountL)) + (iirSampleAR * iirAmountL);
326 			lowSampleR = iirSampleBR;
327 
328 			iirSampleEL = (iirSampleEL * (1 - iirAmountH)) + (inputSampleL * iirAmountH);
329 			iirSampleFL = (iirSampleFL * (1 - iirAmountH)) + (iirSampleEL * iirAmountH);
330 			midSampleL = iirSampleFL - iirSampleBL;
331 
332 			iirSampleER = (iirSampleER * (1 - iirAmountH)) + (inputSampleR * iirAmountH);
333 			iirSampleFR = (iirSampleFR * (1 - iirAmountH)) + (iirSampleER * iirAmountH);
334 			midSampleR = iirSampleFR - iirSampleBR;
335 
336 			highSampleL = inputSampleL - iirSampleFL;
337 			highSampleR = inputSampleR - iirSampleFR;
338 		}
339 		else
340 		{
341 			iirSampleCL = (iirSampleCL * (1 - iirAmountL)) + (inputSampleL * iirAmountL);
342 			iirSampleDL = (iirSampleDL * (1 - iirAmountL)) + (iirSampleCL * iirAmountL);
343 			lowSampleL = iirSampleDL;
344 
345 			iirSampleCR = (iirSampleCR * (1 - iirAmountL)) + (inputSampleR * iirAmountL);
346 			iirSampleDR = (iirSampleDR * (1 - iirAmountL)) + (iirSampleCR * iirAmountL);
347 			lowSampleR = iirSampleDR;
348 
349 			iirSampleGL = (iirSampleGL * (1 - iirAmountH)) + (inputSampleL * iirAmountH);
350 			iirSampleHL = (iirSampleHL * (1 - iirAmountH)) + (iirSampleGL * iirAmountH);
351 			midSampleL = iirSampleHL - iirSampleDL;
352 
353 			iirSampleGR = (iirSampleGR * (1 - iirAmountH)) + (inputSampleR * iirAmountH);
354 			iirSampleHR = (iirSampleHR * (1 - iirAmountH)) + (iirSampleGR * iirAmountH);
355 			midSampleR = iirSampleHR - iirSampleDR;
356 
357 			highSampleL = inputSampleL - iirSampleHL;
358 			highSampleR = inputSampleR - iirSampleHR;
359 		}
360 		fpFlip = !fpFlip;
361 
362 		//generate the tone bands we're using
363 		if (lowSampleL > 1.0) {lowSampleL = 1.0;}
364 		if (lowSampleL < -1.0) {lowSampleL = -1.0;}
365 		if (lowSampleR > 1.0) {lowSampleR = 1.0;}
366 		if (lowSampleR < -1.0) {lowSampleR = -1.0;}
367 		lowSampleL -= (lowSampleL * (fabs(lowSampleL) * 0.448) * (fabs(lowSampleL) * 0.448) );
368 		lowSampleR -= (lowSampleR * (fabs(lowSampleR) * 0.448) * (fabs(lowSampleR) * 0.448) );
369 		lowSampleL *= drive;
370 		lowSampleR *= drive;
371 
372 		if (highSampleL > 1.0) {highSampleL = 1.0;}
373 		if (highSampleL < -1.0) {highSampleL = -1.0;}
374 		if (highSampleR > 1.0) {highSampleR = 1.0;}
375 		if (highSampleR < -1.0) {highSampleR = -1.0;}
376 		highSampleL -= (highSampleL * (fabs(highSampleL) * 0.599) * (fabs(highSampleL) * 0.599) );
377 		highSampleR -= (highSampleR * (fabs(highSampleR) * 0.599) * (fabs(highSampleR) * 0.599) );
378 		highSampleL *= drive;
379 		highSampleR *= drive;
380 
381 		midSampleL = midSampleL * drive;
382 		midSampleR = midSampleR * drive;
383 
384 		long double skew = (midSampleL - lastSampleL);
385 		lastSampleL = midSampleL;
386 		//skew will be direction/angle
387 		long double bridgerectifier = fabs(skew);
388 		if (bridgerectifier > 3.1415926) bridgerectifier = 3.1415926;
389 		//for skew we want it to go to zero effect again, so we use full range of the sine
390 		bridgerectifier = sin(bridgerectifier);
391 		if (skew > 0) skew = bridgerectifier*3.1415926;
392 		else skew = -bridgerectifier*3.1415926;
393 		//skew is now sined and clamped and then re-amplified again
394 		skew *= midSampleL;
395 		//cools off sparkliness and crossover distortion
396 		skew *= 1.557079633;
397 		//crank up the gain on this so we can make it sing
398 		bridgerectifier = fabs(midSampleL);
399 		bridgerectifier += skew;
400 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
401 		bridgerectifier = sin(bridgerectifier);
402 		bridgerectifier *= drive;
403 		bridgerectifier += skew;
404 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
405 		bridgerectifier = sin(bridgerectifier);
406 		if (midSampleL > 0)
407 		{
408 			midSampleL = bridgerectifier;
409 		}
410 		else
411 		{
412 			midSampleL = -bridgerectifier;
413 		}
414 		//blend according to positive and negative controls, left
415 
416 		skew = (midSampleR - lastSampleR);
417 		lastSampleR = midSampleR;
418 		//skew will be direction/angle
419 		bridgerectifier = fabs(skew);
420 		if (bridgerectifier > 3.1415926) bridgerectifier = 3.1415926;
421 		//for skew we want it to go to zero effect again, so we use full range of the sine
422 		bridgerectifier = sin(bridgerectifier);
423 		if (skew > 0) skew = bridgerectifier*3.1415926;
424 		else skew = -bridgerectifier*3.1415926;
425 		//skew is now sined and clamped and then re-amplified again
426 		skew *= midSampleR;
427 		//cools off sparkliness and crossover distortion
428 		skew *= 1.557079633;
429 		//crank up the gain on this so we can make it sing
430 		bridgerectifier = fabs(midSampleR);
431 		bridgerectifier += skew;
432 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
433 		bridgerectifier = sin(bridgerectifier);
434 		bridgerectifier *= drive;
435 		bridgerectifier += skew;
436 		if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
437 		bridgerectifier = sin(bridgerectifier);
438 		if (midSampleR > 0)
439 		{
440 			midSampleR = bridgerectifier;
441 		}
442 		else
443 		{
444 			midSampleR = -bridgerectifier;
445 		}
446 		//blend according to positive and negative controls, right
447 
448 		inputSampleL = ((lowSampleL + midSampleL + highSampleL)/drive)*out;
449 		inputSampleR = ((lowSampleR + midSampleR + highSampleR)/drive)*out;
450 
451 		if (wet !=1.0) {
452 			inputSampleL = (inputSampleL * wet) + (drySampleL * dry);
453 			inputSampleR = (inputSampleR * wet) + (drySampleR * dry);
454 		}
455 
456 		//stereo 64 bit dither, made small and tidy.
457 		int expon; frexp((double)inputSampleL, &expon);
458 		long double dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62);
459 		dither /= 536870912.0; //needs this to scale to 64 bit zone
460 		inputSampleL += (dither-fpNShapeL); fpNShapeL = dither;
461 		frexp((double)inputSampleR, &expon);
462 		dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62);
463 		dither /= 536870912.0; //needs this to scale to 64 bit zone
464 		inputSampleR += (dither-fpNShapeR); fpNShapeR = dither;
465 		//end 64 bit dither
466 
467 		*out1 = inputSampleL;
468 		*out2 = inputSampleR;
469 
470 		in1++;
471 		in2++;
472 		out1++;
473 		out2++;
474     }
475 }
476 
477 } // end namespace DrumSlam
478 
479