1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // $Id: midictrl.h,v 1.16.2.8 2009/11/25 09:09:43 terminator356 Exp $ 5 // 6 // (C) Copyright 1999-2003 Werner Schweer (ws@seh.de) 7 // (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot net) 8 // 9 // This program is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU General Public License 11 // as published by the Free Software Foundation; version 2 of 12 // the License, or (at your option) any later version. 13 // 14 // This program is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with this program; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 // 23 //========================================================= 24 25 #ifndef __MIDICTRL_H__ 26 #define __MIDICTRL_H__ 27 28 #include <map> 29 30 #include "midi_controller.h" 31 32 //#define _MIDI_CTRL_DEBUG_ 33 // For finding exactly who may be calling insert, erase clear etc. in 34 // the controller list classes. (KDevelop 'Find uses'.) 35 //#define _MIDI_CTRL_METHODS_DEBUG_ 36 37 namespace MusECore { 38 39 class Part; 40 class MidiRecordEvent; 41 42 struct MidiCtrlVal 43 { 44 // The part containing the event which this value came from. Used for searching and deleting. 45 Part* part; 46 // The stored value. 47 int val; MidiCtrlValMidiCtrlVal48 MidiCtrlVal(Part* p, int v) { part = p; val = v; } 49 bool operator==(const MidiCtrlVal& mcv) { return part == mcv.part && val == mcv.val; } 50 }; 51 52 //--------------------------------------------------------- 53 // MidiCtrlValList 54 // arrange controller events of a specific type in a 55 // list for easy retrieval 56 //--------------------------------------------------------- 57 58 typedef std::pair<unsigned int, MidiCtrlVal> MidiCtrlValListInsertPair_t; 59 typedef std::multimap<unsigned int, MidiCtrlVal, std::less<unsigned int> > MidiCtrlValList_t; 60 61 class MidiCtrlValList : public MidiCtrlValList_t { 62 63 // The controller number. 64 int ctrlNum; 65 // Current set value in midi hardware. Can be CTRL_VAL_UNKNOWN. 66 double _hwVal; 67 // The last value that was not CTRL_VAL_UNKNOWN. Can still be CTRL_VAL_UNKNOWN (typically at startup). 68 // Note that in the case of PROGRAM for example, HBank/LBank bytes can still be 0xff (OFF). 69 double _lastValidHWVal; 70 // The last byte values that were not CTRL_VAL_UNKNOWN or 0xff (Off). 71 // Can never be 0xff (OFF), but can still be CTRL_VAL_UNKNOWN (typically at startup). 72 // Special for example PROGRAM controller, has 3 separate values: HBank, LBank and Program. 73 int _lastValidByte2; 74 int _lastValidByte1; 75 int _lastValidByte0; 76 77 // Hide built-in finds. find(const unsigned int &)78 iterator find(const unsigned int&) { return end(); }; find(const unsigned int &)79 const_iterator find(const unsigned int&) const { return end(); }; 80 81 public: 82 MidiCtrlValList(int num); 83 84 Part* partAtTick(unsigned int tick) const; 85 86 // Determine value at tick, using values stored by ANY part. 87 iterator iValue(unsigned int tick); 88 // Determine value at tick, using values stored by ANY part. 89 int value(unsigned int tick) const; 90 // Determine value at tick, using values stored by the SPECIFIC part. 91 int value(unsigned int tick, Part* part) const; 92 // Determine value at tick, using values stored by ANY part, 93 // ignoring values that are OUTSIDE of their parts, or muted or off parts or tracks. 94 int visibleValue(unsigned int tick, bool inclMutedParts, bool inclMutedTracks, bool inclOffTracks) const; 95 // Determine value at tick, using values stored by the SPECIFIC part, 96 // ignoring values that are OUTSIDE of the part, or muted or off part or track. 97 int visibleValue(unsigned int tick, Part* part, bool inclMutedParts, bool inclMutedTracks, bool inclOffTracks) const; 98 // Adds the new value. Accepts duplicate controller items at the same position, to accurately reflect 99 // what is really in the event lists. 100 // REMOVE Tim. Ctrl. Changed comment. 101 // // Mostly for the purpose of dragging and dropping controller events and allowing them to be 102 // // on top of each other TEMPORARILY. 103 // // But ultimately once dropping is finished there must be only ONE value per controller 104 // // per position per part. 105 // NOTE: It is FORBIDDEN to have multiple controller events at the same time with the same controller number. 106 // To preserve speed, we RELY on catching that at higher levels like the add event dialog or during song loading. 107 // See detailed comments in EventList::add(). 108 bool addMCtlVal(unsigned int tick, int value, Part* part); 109 // If val is not -1 it will search for that value. 110 void delMCtlVal(unsigned int tick, Part* part, int val/* = -1*/); 111 112 // If val is not -1 it will search for that value. 113 iterator findMCtlVal(unsigned int tick, Part* part, int val/* = -1*/); 114 115 // Current set value in midi hardware. Can be CTRL_VAL_UNKNOWN. hwVal()116 inline int hwVal() const { return MidiController::dValToInt(_hwVal); } 117 hwDVal()118 double hwDVal() const { return _hwVal; } hwValIsUnknown()119 inline bool hwValIsUnknown() const { return MidiController::iValIsUnknown(MidiController::dValToInt(_hwVal)); } 120 121 // Resets the current, and optionally the last, hardware value to CTRL_VAL_UNKNOWN. 122 // Returns true if either value was changed. 123 bool resetHwVal(bool doLastHwValue = false); 124 125 // Set current value in midi hardware. Can be CTRL_VAL_UNKNOWN. 126 // Returns false if value is already equal, true if value is changed. 127 bool setHwVal(const double v); 128 // Sets current and last HW values. 129 // Handy for forcing labels to show 'off' and knobs to show specific values 130 // without having to send two messages. 131 // Returns false if both values are already set, true if either value is changed. 132 bool setHwVals(const double v, const double lastv); 133 // The controller number. num()134 int num() const { return ctrlNum; } 135 // The last value that was not CTRL_VAL_UNKNOWN. Can still be CTRL_VAL_UNKNOWN (typically at startup). 136 // Note that in the case of PROGRAM for example, HBank/LBank bytes can still be 0xff (OFF). lastValidHWVal()137 inline int lastValidHWVal() const { return MidiController::dValToInt(_lastValidHWVal); } 138 lastValidHWDVal()139 double lastValidHWDVal() const { return _lastValidHWVal; } lastHwValIsUnknown()140 inline bool lastHwValIsUnknown() const { return MidiController::iValIsUnknown(MidiController::dValToInt(_lastValidHWVal)); } 141 142 // The last byte values that were not CTRL_VAL_UNKNOWN or 0xff (Off). 143 // Can never be 0xff (OFF), but can still be CTRL_VAL_UNKNOWN (typically at startup). 144 // Special for example PROGRAM controller, has 3 separate values: HBank, LBank and Program. lastValidByte2()145 int lastValidByte2() const { return _lastValidByte2; } lastValidByte1()146 int lastValidByte1() const { return _lastValidByte1; } lastValidByte0()147 int lastValidByte0() const { return _lastValidByte0; } 148 }; 149 150 typedef MidiCtrlValList::iterator iMidiCtrlVal; 151 typedef MidiCtrlValList::const_iterator ciMidiCtrlVal; 152 typedef std::pair <iMidiCtrlVal, iMidiCtrlVal> MidiCtrlValRange; 153 154 //--------------------------------------------------------- 155 // MidiCtrlValListList 156 // List of midi controller value lists. 157 // This list represents the controller state of a 158 // midi port. 159 // index = (channelNumber << 24) + ctrlNumber 160 //--------------------------------------------------------- 161 162 typedef std::map<int, MidiCtrlValList*, std::less<int> > MidiCtrlValListList_t; 163 typedef MidiCtrlValListList_t::iterator iMidiCtrlValList; 164 typedef MidiCtrlValListList_t::const_iterator ciMidiCtrlValList; 165 166 class MidiCtrlValListList : public MidiCtrlValListList_t { 167 bool _RPN_Ctrls_Reserved; 168 169 public: 170 MidiCtrlValListList(); 171 //MidiCtrlValListList(const MidiCtrlValListList&); // TODO 172 find(int channel,int ctrl)173 iterator find(int channel, int ctrl) { 174 return std::map<int, MidiCtrlValList*, std::less<int> >::find((channel << 24) + ctrl); 175 } find(int channel,int ctrl)176 const_iterator find(int channel, int ctrl) const { 177 return ((const MidiCtrlValListList_t*)this)->find((channel << 24) + ctrl); 178 } 179 void clearDelete(bool deleteLists); 180 // Like 'find', finds a controller given fully qualified type + number. 181 // But it returns controller with highest priority if multiple controllers use the 182 // given number such as {Controller7, num = 0x55} + {Controller14, num = 0x5544}. 183 // Note if given number is one of the eight reserved General Midi (N)RPN controllers, 184 // this will only return Controller7 or Controller14, not anything (N)RPN related. 185 // That is, it will not 'encode' (N)RPNs. Use a MidiEncoder instance for that. 186 iMidiCtrlValList searchControllers(int channel, int ctl); 187 // Returns true if any of the EIGHT reserved General Midi (N)RPN control numbers are ALREADY 188 // defined as Controller7 or part of Controller14. Cached, for speed. 189 // Used (at least) by midi input encoders to quickly arbitrate new input. RPN_Ctrls_Reserved()190 bool RPN_Ctrls_Reserved() { return _RPN_Ctrls_Reserved; } 191 // Manual check and update of the flag. For convenience, returns the flag. 192 // Cost depends on types and number of list controllers, so it is good for deferring 193 // an update until AFTER some lengthy list operation. JUST BE SURE to call this! 194 bool update_RPN_Ctrls_Reserved(); 195 196 // NOTICE: If update is false or these are bypassed by using insert, erase, clear etc. for speed, 197 // then BE SURE to call update_RPN_Ctrls_Reserved() later. 198 void add(int channel, MidiCtrlValList* vl, bool update = true); 199 void del(iMidiCtrlValList ictl, bool update = true); 200 size_type del(int num, bool update = true); 201 void del(iMidiCtrlValList first, iMidiCtrlValList last, bool update = true); 202 void clr(); 203 // Convenience method: Resets all current, and optionally the last, hardware controller values to CTRL_VAL_UNKNOWN. 204 // Equivalent to calling resetAllHwVal() on each MidiCtrlValList. 205 // Returns true if either value was changed in any controller. 206 bool resetAllHwVals(bool doLastHwValue); 207 208 #ifdef _MIDI_CTRL_METHODS_DEBUG_ 209 // Need to catch all insert, erase, clear etc... 210 void swap(MidiCtrlValListList&); 211 std::pair<iMidiCtrlValList, bool> insert(const std::pair<int, MidiCtrlValList*>& p); 212 iMidiCtrlValList insert(iMidiCtrlValList ic, const std::pair<int, MidiCtrlValList*>& p); 213 void erase(iMidiCtrlValList ictl); 214 size_type erase(int num); 215 void erase(iMidiCtrlValList first, iMidiCtrlValList last); 216 void clear(); 217 #endif 218 // Some IDEs won't "Find uses" of operators. So, no choice but to trust always catching it here. 219 MidiCtrlValListList& operator=(const MidiCtrlValListList&); 220 }; 221 222 //--------------------------------------------------------- 223 // MidiEncoder 224 //--------------------------------------------------------- 225 226 class MidiEncoder { 227 public: 228 enum Mode { EncIdle, EncCtrl14, EncDiscoverRPN, EncDiscoverNRPN, EncRPN, EncNRPN, EncRPN14, EncNRPN14 }; 229 enum ParamMode { ParamModeUnknown, ParamModeRPN, ParamModeNRPN }; 230 231 private: 232 Mode _curMode; 233 ParamMode _curParamMode; 234 unsigned int _timer; // 235 unsigned char _curCtrl; // Ctl num of first event 236 unsigned char _curData; // Data of first event 237 unsigned int _curTime; // Time of first event 238 unsigned char _nextCtrl; // Expected next event ctl num (for ctrl14 only) 239 unsigned char _curRPNH; 240 unsigned char _curRPNL; 241 unsigned char _curNRPNH; 242 unsigned char _curNRPNL; 243 244 public: 245 MidiEncoder(); 246 247 void encodeEvent(const MidiRecordEvent& ev, int port, int channel); 248 void endCycle(unsigned int blockSize); 249 }; 250 251 extern MidiControllerList defaultMidiController; 252 extern void initMidiController(); 253 254 extern MidiController veloCtrl; 255 extern MidiController pitchCtrl; 256 extern MidiController programCtrl; 257 extern MidiController mastervolCtrl; 258 extern MidiController volumeCtrl; 259 extern MidiController panCtrl; 260 extern MidiController reverbSendCtrl; 261 extern MidiController chorusSendCtrl; 262 extern MidiController variationSendCtrl; 263 264 265 } // namespace MusECore 266 267 #endif 268 269