1 /**
2 * Copyright 2017 Cut Through Recordings
3 * License: MIT License
4 * Author(s): Ethan Reker
5 */
6 module ddsp.effect.dynamics;
7 
8 import ddsp.effect.effect;
9 import ddsp.util.envelope;
10 import ddsp.util.functions;
11 
12 import dplug.core.nogc;
13 
14 import std.algorithm;
15 import std.math;
16 
17 /// Base class for dynamics processors such as compressor, limiter, expander, and gate.
18 /// This class is useless on it's own.  It should be inherited from and have getNextSample overriden.
19 class DynamicsProcessor : AudioEffect
20 {
21 public:
22 nothrow:
23 @nogc:
24 
25     /// Tracks the input level to trigger compression.
26     EnvelopeDetector detector;
27     
28     /// Will point to the detector of a processor that is stereo linked
29     EnvelopeDetector *linkedDetector;
30 
31     this()
32     {
33         x = mallocSlice!float(2);
34         y = mallocSlice!float(2);
35         detector = mallocNew!EnvelopeDetector;
36     }
37     
38     void setParams(float attackTime, float releaseTime, float threshold, float ratio, float knee)
39     {
40         detector.setEnvelope(attackTime, releaseTime);
41         _threshold = threshold;
42         _ratio = ratio;
43         _kneeWidth = knee;
44     }
45     
46     override float getNextSample(const float input)
47     {
48         return 0;
49     }
50     
51     override void reset() nothrow @nogc
52     {
53         
54     }
55     
56     override void setSampleRate(float sampleRate)
57     {
58         _sampleRate = sampleRate;
59         detector.setSampleRate(_sampleRate);
60     }
61     
62     /// Allows this processors envelope to be linked to another processor.
63     /// This way the two will act as a single unit.  Both processors must call
64     /// this on each other to function properly
65     void linkStereo(DynamicsProcessor stereoProcessor) nothrow @nogc
66     {
67         linkedDetector = &stereoProcessor.detector;
68         stereoProcessor.linkedDetector = &this.detector;
69     }
70     
71 protected:
72     /// Amount of input gain in decibels
73     float _inputGain;
74     
75     /// Level in decibels that the input signal must cross before compression begins
76     float _threshold;
77     
78     /// Time in milliseconds before compression begins after threshold has been
79     /// crossed
80     float _attTime;
81     
82     /// Time in milliseconds before the compression releases after the input signal
83     /// has fallen below the threshold
84     float _relTime;
85     
86     /// Ratio of compression, higher ratio = more compression
87     float _ratio;
88     
89     /// Amount of output gain in decibels
90     float _outputGain;
91     
92     /// width of the curve that interpolates between input and output.  Unit in
93     /// decibels
94     float _kneeWidth;
95     
96     /// Holds the points used for interpolation;
97     float[]  x, y;
98 
99     //DynamicsProcessor _linkedProcessor;
100 }