1 /*
2  * MIDI CC Map X4 plugin based on DISTRHO Plugin Framework (DPF)
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Copyright (C) 2020 Christopher Arndt <info@chrisarndt.de>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to
10  * deal in the Software without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12  * sell copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26 
27 #ifndef PLUGIN_MIDICCMAPX4_H
28 #define PLUGIN_MIDICCMAPX4_H
29 
30 #include "DistrhoPlugin.hpp"
31 
32 START_NAMESPACE_DISTRHO
33 
34 #ifndef IN_RANGE
35 #define IN_RANGE(v, min, max) ((min) <= (max) ? ((v) >= (min) && (v) <= (max)) : ((v) >= (min) || (v) <= (max)))
36 #endif
37 
38 #ifndef MAP
39 #define MAP(v, imin, imax, omin, omax) (((v) - (imin)) * ((omax) - (omin)) / ((imax) - (imin)) + (omin))
40 #endif
41 
42 #ifndef MIN
43 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
44 #endif
45 
46 #ifndef MAX
47 #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
48 #endif
49 
50 #ifndef CLAMP
51 #define CLAMP(v, min, max) (MIN((max), MAX((min), (v))))
52 #endif
53 
54 #define MIDI_CONTROL_CHANGE 0xB0
55 
56 // -----------------------------------------------------------------------
57 
58 class PluginMIDICCMapX4 : public Plugin {
59 public:
60     enum Parameters {
61         paramFilterChannel,
62         paramCCSource,
63         paramKeepOriginal,
64         paramCC1Mode,
65         paramCC1Dest,
66         paramCC1Channel,
67         paramCC1FilterDups,
68         paramCC1Start,
69         paramCC1End,
70         paramCC1Min,
71         paramCC1Max,
72         paramCC2Mode,
73         paramCC2Dest,
74         paramCC2Channel,
75         paramCC2FilterDups,
76         paramCC2Start,
77         paramCC2End,
78         paramCC2Min,
79         paramCC2Max,
80         paramCC3Mode,
81         paramCC3Dest,
82         paramCC3Channel,
83         paramCC3FilterDups,
84         paramCC3Start,
85         paramCC3End,
86         paramCC3Min,
87         paramCC3Max,
88         paramCC4Mode,
89         paramCC4Dest,
90         paramCC4Channel,
91         paramCC4FilterDups,
92         paramCC4Start,
93         paramCC4End,
94         paramCC4Min,
95         paramCC4Max,
96         paramCount
97     };
98 
99     PluginMIDICCMapX4();
100 
101 protected:
102     // -------------------------------------------------------------------
103     // Information
104 
getLabel() const105     const char* getLabel() const noexcept override {
106         return "MIDICCMapX4";
107     }
108 
getDescription() const109     const char* getDescription() const override {
110         return "Map a single input CC to up to four output CCs";
111     }
112 
getMaker() const113     const char* getMaker() const noexcept override {
114         return "chrisarndt.de";
115     }
116 
getHomePage() const117     const char* getHomePage() const override {
118         return DISTRHO_PLUGIN_URI;
119     }
120 
getLicense() const121     const char* getLicense() const noexcept override {
122         return "https://spdx.org/licenses/MIT";
123     }
124 
getVersion() const125     uint32_t getVersion() const noexcept override {
126         return d_version(1, 0, 0);
127     }
128 
129     // Go to:
130     //
131     // http://service.steinberg.de/databases/plugin.nsf/plugIn
132     //
133     // Get a proper plugin UID and fill it in here!
getUniqueId() const134     int64_t getUniqueId() const noexcept override {
135         return d_cconst('M', 'C', 'C', '4');
136     }
137 
138     // -------------------------------------------------------------------
139     // Init
140 
141     void initParameter(uint32_t index, Parameter& parameter) override;
142     void initPortGroup(uint32_t index, PortGroup& pgroup) override;
143     void initProgramName(uint32_t index, String& programName) override;
144 
145     // -------------------------------------------------------------------
146     // Internal data
147 
148     float getParameterValue(uint32_t index) const override;
149     void setParameterValue(uint32_t index, float value) override;
150     void loadProgram(uint32_t index) override;
151 
152     // -------------------------------------------------------------------
153     // Optional
154 
155     // Optional callback to inform the plugin about a sample rate change.
156     void sampleRateChanged(double newSampleRate) override;
157 
158     // -------------------------------------------------------------------
159     // Process
160 
161     void activate() override;
162 
163     void run(const float**, float**, uint32_t,
164              const MidiEvent* midiEvents, uint32_t midiEventCount) override;
165 
166 
167     // -------------------------------------------------------------------
168 
169 private:
170     float fParams[paramCount];
171     int8_t filterChannel;
172     int8_t lastCCValue[16][128];
173 
174     DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginMIDICCMapX4)
175 };
176 
177 struct Preset {
178     const char* name;
179     const float params[PluginMIDICCMapX4::paramCount];
180 };
181 
182 const Preset factoryPresets[] = {
183     {
184         "Default",
185         {
186             0.0,    // Filter Channel
187             0.0,    // Keep Source CC
188             1.0,    // Source CC
189             0.0,    // CC1 Mode
190             14.0,   // CC1 Dest
191             0.0,    // CC1 Channel
192             1.0,    // CC1 Keep Dups
193             0.0,    // CC1 Start
194             127.0,  // CC1 End
195             0.0,    // CC1 Min
196             127.0,  // CC1 Max
197             0.0,    // CC2 Mode
198             15.0,   // CC2 Dest
199             0.0,    // CC2 Channel
200             1.0,    // CC2 Keep Dups
201             0.0,    // CC2 Start
202             127.0,  // CC2 End
203             0.0,    // CC2 Min
204             127.0,  // CC2 Max
205             0.0,    // CC3 Mode
206             16.0,   // CC3 Dest
207             0.0,    // CC3 Channel
208             1.0,    // CC3 Keep Dups
209             0.0,    // CC3 Start
210             127.0,  // CC3 End
211             0.0,    // CC3 Min
212             127.0,  // CC3 Max
213             0.0,    // CC4 Mode
214             17.0,   // CC4 Dest
215             0.0,    // CC4 Channel
216             1.0,    // CC4 Keep Dups
217             0.0,    // CC4 Start
218             127.0,  // CC4 End
219             0.0,    // CC4 Min
220             127.0,  // CC4 Max
221         }
222     },
223 };
224 
225 const uint presetCount = sizeof(factoryPresets) / sizeof(Preset);
226 
227 // -----------------------------------------------------------------------
228 
229 END_NAMESPACE_DISTRHO
230 
231 #endif  // #ifndef PLUGIN_MIDICCMAPX4_H
232