1 /* 2 * MIDI CCRecorder plugin based on DISTRHO Plugin Framework (DPF) 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Copyright (C) 2019 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_MIDICCRECORDER_H 28 #define PLUGIN_MIDICCRECORDER_H 29 30 #include "DistrhoPlugin.hpp" 31 32 START_NAMESPACE_DISTRHO 33 34 #ifndef MAP 35 #define MAP(v, imin, imax, omin, omax) (((v) - (imin)) * ((omax) - (omin)) / ((imax) - (imin)) + (omin)) 36 #endif 37 38 #ifndef MIN 39 #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) 40 #endif 41 42 #ifndef MAX 43 #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) 44 #endif 45 46 #ifndef CLAMP 47 #define CLAMP(v, min, max) (MIN((max), MAX((min), (v)))) 48 #endif 49 50 #define MIDI_CONTROL_CHANGE 0xB0 51 #define MIDI_PROGRAM_CHANGE 0xC0 52 #define NUM_CHANNELS 16 53 #define NUM_CONTROLLERS 128 54 55 // ----------------------------------------------------------------------- 56 57 class PluginMIDICCRecorder : public Plugin { 58 public: 59 enum Parameters { 60 paramRecordEnable = 0, 61 paramTrigClear, 62 paramTrigSend, 63 paramTrigTransport, 64 paramTrigPCChannel, 65 paramTrigPC, 66 paramSendChannel, 67 paramSendInterval, 68 paramCount 69 }; 70 71 PluginMIDICCRecorder(); 72 73 protected: 74 // ------------------------------------------------------------------- 75 // Information 76 getLabel() const77 const char* getLabel() const noexcept override { 78 return "MIDICCRecorder"; 79 } 80 getDescription() const81 const char* getDescription() const override { 82 return "Store received Control Change messages and replay them when triggered"; 83 } 84 getMaker() const85 const char* getMaker() const noexcept override { 86 return "chrisarndt.de"; 87 } 88 getHomePage() const89 const char* getHomePage() const override { 90 return "https://chrisarndt.de/plugins/midiccrecorder"; 91 } 92 getLicense() const93 const char* getLicense() const noexcept override { 94 return "https://spdx.org/licenses/MIT"; 95 } 96 getVersion() const97 uint32_t getVersion() const noexcept override { 98 return d_version(0, 3, 0); 99 } 100 101 // Go to: 102 // 103 // http://service.steinberg.de/databases/plugin.nsf/plugIn 104 // 105 // Get a proper plugin UID and fill it in here! getUniqueId() const106 int64_t getUniqueId() const noexcept override { 107 return d_cconst('M', 'C', 'c', 'r'); 108 } 109 110 // ------------------------------------------------------------------- 111 // Init 112 113 void initParameter(uint32_t index, Parameter& parameter) override; 114 void initProgramName(uint32_t index, String& programName) override; 115 void initState(uint32_t index, String& stateKey, String& defaultStateValue) override; 116 117 // ------------------------------------------------------------------- 118 // Internal data 119 120 float getParameterValue(uint32_t index) const override; 121 void setParameterValue(uint32_t index, float value) override; 122 void loadProgram(uint32_t index) override; 123 String getState(const char* key) const override; 124 void setState(const char* key, const char* value) override; 125 void clearState(); 126 127 // ------------------------------------------------------------------- 128 // Optional 129 130 // Optional callback to inform the plugin about a sample rate change. 131 void sampleRateChanged(double newSampleRate) override; 132 133 // ------------------------------------------------------------------- 134 // Process 135 136 void activate() override; 137 void startSend(); 138 void run(const float**, float**, uint32_t, 139 const MidiEvent* midiEvents, uint32_t midiEventCount) override; 140 141 // ------------------------------------------------------------------- 142 143 private: 144 float fParams[paramCount]; 145 double fSampleRate; 146 uint8_t stateCC[NUM_CHANNELS][NUM_CONTROLLERS]; 147 uint8_t curChan, curCC, sendChannel; 148 bool playing, sendInProgress; 149 150 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginMIDICCRecorder) 151 }; 152 153 struct Preset { 154 const char* name; 155 float params[PluginMIDICCRecorder::paramCount]; 156 }; 157 158 Preset factoryPresets[] = { 159 { 160 "Default", 161 {0, 0, 0, 0, 17, 0, 0, 1.0} 162 }, 163 }; 164 165 constexpr uint presetCount = sizeof(factoryPresets) / sizeof(Preset); 166 constexpr uint stateCount = NUM_CHANNELS; 167 168 // ----------------------------------------------------------------------- 169 170 END_NAMESPACE_DISTRHO 171 172 #endif // #ifndef PLUGIN_MIDICCRECORDER_H 173