View difference between Paste ID: yiYaNK1X and vbHL2Knr
SHOW: | | - or go back to the newest paste.
1
**UPDATE: I dug around in the Surge source code and found the relevant bits here, I hope this helps**
2
3
```
4
class ControllerModulationSource : public ModulationSource
5
{
6
  public:
7
    // Smoothing and Shaping Behaviors
8
    enum SmoothingMode
9
    {
10
        LEGACY = -1, // This is (1) the exponential backoff and (2) not streamed.
11
        SLOW_EXP,    // Legacy with a sigma clamp
12
        FAST_EXP,    // Faster Legacy with a sigma clamp
13
        FAST_LINE,   // Linearly move
14
        DIRECT       // Apply the value directly
15
    } smoothingMode = LEGACY;
16
17
    ControllerModulationSource()
18
    {
19
        target = 0.f;
20
        output = 0.f;
21
        bipolar = false;
22
        changed = true;
23
        smoothingMode = LEGACY;
24
    }
25
    ControllerModulationSource(SmoothingMode mode) : ControllerModulationSource()
26
    {
27
        smoothingMode = mode;
28
    }
29
30
    virtual ~ControllerModulationSource() {}
31
    void set_target(float f)
32
    {
33
        target = f;
34
        startingpoint = output;
35
        changed = true;
36
    }
37
38
    void init(float f)
39
    {
40
        target = f;
41
        output = f;
42
        startingpoint = f;
43
        changed = true;
44
    }
45
46
    void set_target01(float f, bool updatechanged = true)
47
    {
48
        if (bipolar)
49
            target = 2.f * f - 1.f;
50
        else
51
            target = f;
52
        startingpoint = output;
53
        if (updatechanged)
54
            changed = true;
55
    }
56
57
    virtual float get_output01(int i) override
58
    {
59
        if (bipolar)
60
            return 0.5f + 0.5f * output;
61
        return output;
62
    }
63
64
    virtual float get_target01()
65
    {
66
        if (bipolar)
67
            return 0.5f + 0.5f * target;
68
        return target;
69
    }
70
71
    virtual bool has_changed(bool reset)
72
    {
73
        if (changed)
74
        {
75
            if (reset)
76
                changed = false;
77
            return true;
78
        }
79
        return false;
80
    }
81
82
    virtual void reset() override
83
    {
84
        target = 0.f;
85
        output = 0.f;
86
        bipolar = false;
87
    }
88
    inline void processSmoothing(SmoothingMode mode, float sigma)
89
    {
90
        if (mode == LEGACY || mode == SLOW_EXP || mode == FAST_EXP)
91
        {
92
            float b = fabs(target - output);
93-
            if (b < sigma &amp;&amp; mode != LEGACY)
93+
            if (b < sigma && mode != LEGACY)
94
            {
95
                output = target;
96
            }
97
            else
98
            {
99
                float a = (mode == FAST_EXP ? 0.99f : 0.9f) * 44100 * samplerate_inv * b;
100
                output = (1 - a) * output + a * target;
101
            }
102
            return;
103
        };
104
        if (mode == FAST_LINE)
105
        {
106
            /*
107
             * Apply a constant change until we get there.
108
             * Rate is set so we cover the entire range (0,1)
109
             * in 50 blocks at 44k
110
             */
111
            float sampf = samplerate / 44100;
112
            float da = (target - startingpoint) / (50 * sampf);
113
            float b = target - output;
114
            if (fabs(b) < fabs(da))
115
            {
116
                output = target;
117
            }
118
            else
119
            {
120
                output += da;
121
            }
122
        }
123
        if (mode == DIRECT)
124
        {
125
            output = target;
126
        }
127
    }
128
    virtual void process_block() override
129
    {
130
        processSmoothing(smoothingMode, smoothingMode == FAST_EXP ? 0.005f : 0.0025f);
131
    }
132
133
    virtual bool process_block_until_close(float sigma)
134
    {
135
        if (smoothingMode == LEGACY)
136
            processSmoothing(SLOW_EXP, sigma);
137
        else
138
            processSmoothing(smoothingMode, sigma);
139
140
        return (output != target); // continue
141
    }
142
143
    virtual bool is_bipolar() override { return bipolar; }
144
    virtual void set_bipolar(bool b) override { bipolar = b; }
145
146
    float target, startingpoint;
147
    int id; // can be used to assign the controller to a parameter id
148
    bool bipolar;
149
    bool changed;
150
};
151
```
152
153
**And then, elsewhere in the code, the smoothing is applied to these midi signals:**
154
155
```
156
        scene.modsources[ms_modwheel] = new ControllerModulationSource(storage.smoothingMode);
157
        scene.modsources[ms_breath] = new ControllerModulationSource(storage.smoothingMode);
158
        scene.modsources[ms_expression] = new ControllerModulationSource(storage.smoothingMode);
159
        scene.modsources[ms_sustain] = new ControllerModulationSource(storage.smoothingMode);
160
        scene.modsources[ms_aftertouch] = new ControllerModulationSource(storage.smoothingMode);
161
        scene.modsources[ms_pitchbend] = new ControllerModulationSource(storage.smoothingMode);
162
        scene.modsources[ms_lowest_key] = new ControllerModulationSource(storage.smoothingMode);
163
        scene.modsources[ms_highest_key] = new ControllerModulationSource(storage.smoothingMode);
164
        scene.modsources[ms_latest_key] = new ControllerModulationSource(storage.smoothingMode);
165
```