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 __MIDI_CONTROLLER_H__ 26 #define __MIDI_CONTROLLER_H__ 27 28 #include <map> 29 30 #include <QString> 31 32 #include "midictrl_consts.h" 33 #include "xml.h" 34 35 //#define _MIDI_CTRL_DEBUG_ 36 // For finding exactly who may be calling insert, erase clear etc. in 37 // the controller list classes. (KDevelop 'Find uses'.) 38 //#define _MIDI_CTRL_METHODS_DEBUG_ 39 40 namespace MusECore { 41 42 //--------------------------------------------------------- 43 // MidiController 44 //--------------------------------------------------------- 45 46 class MidiController { 47 public: 48 // 49 // mapping of midi controller types to 50 // controller number: 51 // 52 enum ControllerType { 53 Controller7, // num values from 0 - 0x7f 54 Controller14, // values from 0x10000 - 0x12fff 55 RPN, // registered parameter 0x20000 - 56 NRPN, // non registered parameter 0x30000 - 57 RPN14, // registered parameter 0x50000 58 NRPN14, // non registered parameter 0x60000 - 59 Pitch, // num value = CTRL_PITCH 60 Program, // num value = CTRL_PROGRAM 61 PolyAftertouch, // num value = CTRL_POLYAFTER 62 Aftertouch, // num value = CTRL_AFTERTOUCH 63 Velo // not assigned 64 }; 65 66 enum ShowInTrackType { ShowInDrum=1, ShowInMidi=2 }; 67 68 protected: 69 QString _name; 70 int _num; // Controller Number 71 int _minVal; // controller value range (used in gui) 72 int _maxVal; 73 int _initVal; 74 // Special for drum mode, for controllers such as program. 75 int _drumInitVal; 76 int _bias; 77 int _showInTracks; 78 void updateBias(); 79 80 public: 81 MidiController(); 82 // If drumInit = -1, it means don't care - use the init val. 83 MidiController(const QString& n, int num, int min, int max, int init, int drumInit, int show_in_track = (ShowInDrum | ShowInMidi)); 84 MidiController(const MidiController& mc); 85 void copy(const MidiController &mc); 86 MidiController& operator= (const MidiController &mc); 87 88 // Convert given controller double value to integer. dValToInt(double v)89 static inline int dValToInt(double v) { 90 // TODO: Decide best choice here. 91 //return int(round(v)); 92 //return lrint(v); 93 return int(v); 94 } 95 96 // Whether the given integer value is CTRL_VAL_UNKNOWN. iValIsUnknown(int v)97 static inline bool iValIsUnknown(int v) { return v == CTRL_VAL_UNKNOWN; } 98 // Whether the given double value is CTRL_VAL_UNKNOWN. dValIsUnknown(double v)99 static inline bool dValIsUnknown(double v) { return iValIsUnknown(dValToInt(v)); } 100 name()101 const QString& name() const { return _name; } num()102 int num() const { return _num; } 103 ControllerType type() const; setName(const QString & s)104 void setName(const QString& s) { _name = s; } setNum(int v)105 void setNum(int v) { _num = v; } 106 void write(int level, Xml& xml) const; 107 void read(Xml& xml); minVal()108 int minVal() const { return _minVal; } maxVal()109 int maxVal() const { return _maxVal; } initVal()110 int initVal() const { return _initVal; } initValIsUnknown()111 inline bool initValIsUnknown() const { return iValIsUnknown(_initVal); } setInitVal(int val)112 void setInitVal(int val) { _initVal = val; } drumInitVal()113 int drumInitVal() const { return _drumInitVal; } drumInitValIsUnknown()114 inline bool drumInitValIsUnknown() const { return iValIsUnknown(_drumInitVal); } setDrumInitVal(int val)115 void setDrumInitVal(int val) { _drumInitVal = val; } setMinVal(int val)116 void setMinVal(int val) { _minVal = val; updateBias(); } setMaxVal(int val)117 void setMaxVal(int val) { _maxVal = val; updateBias(); } bias()118 int bias() const { return _bias; } showInTracks()119 int showInTracks() const { return _showInTracks; } setShowInTracks(int i)120 void setShowInTracks(int i) { _showInTracks = i; } 121 bool isPerNoteController() const; 122 static int genNum(ControllerType, int, int); 123 }; 124 125 126 //--------------------------------------------------------- 127 // MidiControllerList 128 // this is a list of used midi controllers created 129 // - explicit by user 130 // - implicit during import of a midi file 131 //--------------------------------------------------------- 132 133 typedef std::map<int, MidiController*, std::less<int> > MidiControllerList_t; 134 135 class MidiControllerList : public MidiControllerList_t 136 { 137 bool _RPN_Ctrls_Reserved; 138 139 public: 140 MidiControllerList(); 141 MidiControllerList(const MidiControllerList& mcl); 142 // NOTE: There is no destructor here, this container does not 143 // delete its own contents, that is done in ~MidiInstrument 144 // because some controls are shared (the ones in 145 // defaultMidiController and defaultManagedMidiController). 146 // However, an inheritor such as the class MidiNamCtrls 147 // found in the MidNam module DOES delete its own. 148 149 // Like find() which finds a verbose ctl number, but this version also finds a per-note 150 // controller if there is one for the given ctl number, if no verbose one was found. 151 // Returns null if no controller found. The ctl number can be the 'real' controller number, 152 // ie the low byte can be the actual note number and does not have to be 0xff. 153 MidiController* findController(int ctl) const; 154 // Returns per-note controller if there is one for the given ctl number. 155 // Otherwise returns null. The ctl number can be the 'real' controller number, 156 // ie the low byte can be the actual note number and does not have to be 0xff. 157 MidiController* perNoteController(int ctl) const; 158 159 // Like 'find', finds a controller given fully qualified type + number. 160 // But it returns controller with highest priority if multiple controllers use the 161 // given number such as {Controller7, num = 0x55} + {Controller14, num = 0x5544}. 162 // Note if given number is one of the eight reserved General Midi (N)RPN controllers, 163 // this will only return Controller7 or Controller14, not anything (N)RPN related. 164 // That is, it will not 'encode' (N)RPNs. Use a MidiEncoder instance for that. 165 iterator searchControllers(int ctl); 166 // Check if either a per-note controller, or else a regular controller already exists. 167 bool ctrlAvailable(int find_num, MidiController* ignore_this = 0); 168 // Returns true if any of the EIGHT reserved General Midi (N)RPN control numbers are 169 // ALREADY defined as Controller7 or part of Controller14. Cached, for speed. 170 // Used (at least) by midi input encoders to quickly arbitrate new input. RPN_Ctrls_Reserved()171 bool RPN_Ctrls_Reserved() { return _RPN_Ctrls_Reserved; } 172 // Manual check and update of the flag. For convenience, returns the flag. 173 bool update_RPN_Ctrls_Reserved(); 174 175 // NOTICE: If update is false or these are bypassed by using insert, erase, clear etc. for speed, 176 // then BE SURE to call update_RPN_Ctrls_Reserved() later. 177 // Returns true if add is successful. 178 bool add(MidiController* mc, bool update = true); 179 void del(iterator ictl, bool update = true); 180 size_type del(int num, bool update = true); 181 void del(iterator first, iterator last, bool update = true); 182 void clr(); 183 184 #ifdef _MIDI_CTRL_METHODS_DEBUG_ 185 // Need to catch all insert, erase, clear etc... 186 void swap(MidiControllerList&); 187 std::pair<iterator, bool> insert(const std::pair<int, MidiController*>& p); 188 iterator insert(iterator ic, const std::pair<int, MidiController*>& p); 189 void erase(iterator ictl); 190 size_type erase(int num); 191 void erase(iterator first, iterator last); 192 void clear(); 193 #endif 194 // Some IDEs won't "Find uses" of operators. So, no choice but to trust always catching it here. 195 MidiControllerList& operator=(const MidiControllerList&); 196 }; 197 198 typedef MidiControllerList::iterator iMidiController; 199 typedef MidiControllerList::const_iterator ciMidiController; 200 typedef std::pair<int /* number */, MidiController*> MidiControllerListPair; 201 202 extern MidiController::ControllerType midiControllerType(int num); 203 extern int midiCtrlTerms2Number(MidiController::ControllerType type, int ctrl = 0); 204 extern bool isPerNoteMidiController(int num); 205 206 207 extern const QString& int2ctrlType(int n); 208 extern MidiController::ControllerType ctrlType2Int(const QString& s); 209 extern QString midiCtrlName(int ctrl, bool fullyQualified = false); 210 extern QString midiCtrlNumString(int ctrl, bool fullyQualified = false); 211 212 typedef std::map<int, int, std::less<int> > MidiCtl2LadspaPortMap; 213 typedef MidiCtl2LadspaPortMap::iterator iMidiCtl2LadspaPort; 214 typedef MidiCtl2LadspaPortMap::const_iterator ciMidiCtl2LadspaPort; 215 216 217 // // REMOVE Tim. midnam. Added. 218 // // template<class Key, class T, class Compare = std::less<Key>, 219 // // class Alloc = std::allocator<std::pair<const Key,T> > > 220 // // class CompoundMidiControllerList_t : public MidiControllerList_t 221 // class CompoundMidiControllerList_t : public MidiControllerList 222 // { 223 // private: 224 // // typedef std::multimap<Key, T, Compare, Alloc> vlist; 225 // // typedef MidiControllerList_t vlist; 226 // typedef MidiControllerList vlist; 227 // //typedef typename std::list<T>::const_iterator cil_t; 228 // 229 // //MidiControllerList** _p_other; 230 // //MidNamMIDIName* _midnamDocument; 231 // 232 // protected: 233 // //Pos::TType _type; 234 // MidiControllerList** _p_other; 235 // 236 // public: 237 // typedef typename vlist::iterator iCompoundMidiControllerList_t; 238 // typedef typename vlist::const_iterator ciCompoundMidiControllerList_t; 239 // // typedef std::pair <ciMixedPosList_t, ciMixedPosList_t> cMixedPosListRange_t; 240 // // typedef std::pair <Key, T> MixedPosListInsertPair_t; 241 // typedef std::pair <int, MidiController*> CompoundMidiControllerListInsertPair_t; 242 // 243 // 244 // class iterator : public vlist::iterator { 245 // protected: 246 // const MidiControllerList* _p_list; 247 // MidiControllerList** _p_other; 248 // bool _isFromOther; 249 // 250 // public: 251 // iterator() : vlist::iterator(), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 252 // iterator(vlist::iterator i) : vlist::iterator(i), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 253 // 254 // void setLists(const MidiControllerList* this_list, MidiControllerList** other, bool isFromOther) 255 // { _p_list = this_list; _p_other = other; _isFromOther = isFromOther; } 256 // 257 // // MidiController* operator*() { 258 // // //return (MidiController*)(**((vlist::iterator*)this)); 259 // // return (MidiController*)(**((vlist::iterator*)this->second)); 260 // // } 261 // iterator operator++(int) { 262 // return iterator ((*(vlist::iterator*)this).operator++(0)); 263 // } 264 // iterator& operator++() { 265 // vlist::iterator i_this = *this; 266 // i_this++; 267 // if(_p_other && !(*_p_other)->empty()) 268 // { 269 // 270 // } 271 // 272 // (iterator&) ((*(vlist::iterator*)this).operator++()) 273 // 274 // 275 // return (iterator&) ((*(vlist::iterator*)this).operator++()); 276 // } 277 // }; 278 // 279 // class const_iterator : public vlist::const_iterator { 280 // protected: 281 // const MidiControllerList* _p_list; 282 // MidiControllerList** _p_other; 283 // bool _isFromOther; 284 // 285 // public: 286 // const_iterator() : vlist::const_iterator(), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 287 // const_iterator(vlist::const_iterator i) 288 // : vlist::const_iterator(i), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 289 // const_iterator(vlist::iterator i) 290 // : vlist::const_iterator(i), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 291 // 292 // void setLists(const MidiControllerList* this_list, MidiControllerList** other, bool isFromOther) 293 // { _p_list = this_list; _p_other = other; _isFromOther = isFromOther; } 294 // 295 // // const T operator*() const { 296 // // return (T)(**((vlist::const_iterator*)this)); 297 // // } 298 // std::pair <int, MidiController*> operator*() const { 299 // return **((vlist::const_iterator*)this); 300 // } 301 // // const MidiController* operator->() const { 302 // // return (**((vlist::const_iterator*)this)->second); 303 // // } 304 // }; 305 // 306 // class reverse_iterator : public vlist::reverse_iterator { 307 // protected: 308 // const MidiControllerList* _p_list; 309 // MidiControllerList** _p_other; 310 // bool _isFromOther; 311 // 312 // public: 313 // reverse_iterator() : vlist::reverse_iterator(), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 314 // reverse_iterator(vlist::reverse_iterator i) 315 // : vlist::reverse_iterator(i), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 316 // 317 // void setLists(const MidiControllerList* this_list, MidiControllerList** other, bool isFromOther) 318 // { _p_list = this_list; _p_other = other; _isFromOther = isFromOther; } 319 // 320 // // T operator*() { 321 // // return (T)(**((vlist::reverse_iterator*)this)); 322 // // } 323 // std::pair <int, MidiController*> operator*() { 324 // return **((vlist::reverse_iterator*)this); 325 // } 326 // }; 327 // 328 // class const_reverse_iterator : public vlist::const_reverse_iterator { 329 // protected: 330 // const MidiControllerList* _p_list; 331 // MidiControllerList** _p_other; 332 // bool _isFromOther; 333 // 334 // public: 335 // const_reverse_iterator() : vlist::const_reverse_iterator(), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 336 // const_reverse_iterator(vlist::const_reverse_iterator i) 337 // : vlist::const_reverse_iterator(i), _p_list(nullptr), _p_other(nullptr), _isFromOther(false) {} 338 // 339 // void setLists(const MidiControllerList* this_list, MidiControllerList** other, bool isFromOther) 340 // { _p_list = this_list; _p_other = other; _isFromOther = isFromOther; } 341 // 342 // // T operator*() { 343 // // return (T)(**((vlist::const_reverse_iterator*)this)); 344 // // } 345 // std::pair <int, MidiController*> operator*() { 346 // return **((vlist::const_reverse_iterator*)this); 347 // } 348 // }; 349 // 350 // 351 // 352 // 353 // //CompoundMidiControllerList_t(Pos::TType type = Pos::TICKS) : vlist(), _type(type) {} 354 // CompoundMidiControllerList_t(MidiControllerList** other = nullptr) 355 // : vlist(), _p_other(other) { } 356 // 357 // virtual ~CompoundMidiControllerList_t() {} 358 // 359 // //inline Pos::TType type() const { return _type; } 360 // //inline void setType(const Pos::TType& t) { _type = t; rebuild(); } 361 // 362 // iterator begin() noexcept 363 // { 364 // iterator i_this = vlist::begin(); 365 // i_this.setLists(this, _p_other, false); 366 // if(_p_other && !(*_p_other)->empty()) 367 // { 368 // iterator i_other = (*_p_other)->begin(); 369 // i_other.setLists(this, _p_other, true); 370 // if(vlist::empty() || i_other->first < i_this->first) 371 // return i_other; 372 // } 373 // return i_this; 374 // } 375 // 376 // const_iterator begin() const noexcept 377 // { 378 // const_iterator i_this = vlist::begin(); 379 // i_this.setLists(this, _p_other, false); 380 // if(_p_other && !(*_p_other)->empty()) 381 // { 382 // const MidiControllerList* mcl_other = *_p_other; 383 // const_iterator i_other = mcl_other->begin(); 384 // i_other.setLists(this, _p_other, true); 385 // if(vlist::empty() || i_other->first < i_this->first) 386 // return i_other; 387 // } 388 // return i_this; 389 // } 390 // 391 // const_iterator cbegin() const noexcept 392 // { 393 // const_iterator i_this = vlist::cbegin(); 394 // i_this.setLists(this, _p_other, false); 395 // if(_p_other && !(*_p_other)->empty()) 396 // { 397 // const_iterator i_other = (*_p_other)->cbegin(); 398 // i_other.setLists(this, _p_other, true); 399 // if(vlist::empty() || i_other->first < i_this->first) 400 // return i_other; 401 // } 402 // return i_this; 403 // } 404 // 405 // reverse_iterator rbegin() noexcept 406 // { 407 // reverse_iterator i_this = vlist::rbegin(); 408 // i_this.setLists(this, _p_other, false); 409 // if(_p_other && !(*_p_other)->empty()) 410 // { 411 // reverse_iterator i_other = (*_p_other)->rbegin(); 412 // i_other.setLists(this, _p_other, true); 413 // if(vlist::empty() || i_other->first > i_this->first) 414 // return i_other; 415 // } 416 // return i_this; 417 // } 418 // 419 // const_reverse_iterator rbegin() const noexcept 420 // { 421 // const_reverse_iterator i_this = vlist::rbegin(); 422 // i_this.setLists(this, _p_other, false); 423 // if(_p_other && !(*_p_other)->empty()) 424 // { 425 // const MidiControllerList* mcl_other = *_p_other; 426 // const_reverse_iterator i_other = mcl_other->rbegin(); 427 // i_other.setLists(this, _p_other, true); 428 // if(vlist::empty() || i_other->first > i_this->first) 429 // return i_other; 430 // } 431 // return i_this; 432 // } 433 // 434 // const_reverse_iterator crbegin() const noexcept 435 // { 436 // const_reverse_iterator i_this = vlist::crbegin(); 437 // i_this.setLists(this, _p_other, false); 438 // if(_p_other && !(*_p_other)->empty()) 439 // { 440 // const_reverse_iterator i_other = (*_p_other)->crbegin(); 441 // i_other.setLists(this, _p_other, true); 442 // if(vlist::empty() || i_other->first > i_this->first) 443 // return i_other; 444 // } 445 // return i_this; 446 // } 447 // 448 // 449 // // ------------------------------------------------------------------- 450 // // With these end iterators, we have a choice of either container. 451 // // We could ask which container's end is more relevant by comparing 452 // // the decremented end iterators, or we could simply just take the 453 // // first container's. Which ever way we choose, it MUST be 454 // // consistent with the way our operator++/-- work. 455 // // ------------------------------------------------------------------- 456 // 457 // iterator end() noexcept 458 // { 459 // iterator i_this = vlist::end(); 460 // i_this.setLists(this, _p_other, false); 461 // // if(_p_other && !(*_p_other)->empty()) 462 // // { 463 // // iterator i_other = (*_p_other)->end(); 464 // // i_other.setLists(this, _p_other, true); 465 // // if(vlist::empty() || i_other->first > i_this->first) 466 // // return i_other; 467 // // } 468 // return i_this; 469 // } 470 // 471 // const_iterator end() const noexcept 472 // { 473 // const_iterator i_this = vlist::end(); 474 // i_this.setLists(this, _p_other, false); 475 // // if(_p_other && !(*_p_other)->empty()) 476 // // { 477 // // const_iterator i_other = (*_p_other)->end(); 478 // // i_other.setLists(this, _p_other, true); 479 // // if(vlist::empty() || i_other->first > i_this->first) 480 // // return i_other; 481 // // } 482 // return i_this; 483 // } 484 // 485 // const_iterator cend() const noexcept 486 // { 487 // const_iterator i_this = vlist::cend(); 488 // i_this.setLists(this, _p_other, false); 489 // // if(_p_other && !(*_p_other)->empty()) 490 // // { 491 // // const_iterator i_other = (*_p_other)->cend(); 492 // // i_other.setLists(this, _p_other, true); 493 // // if(vlist::empty() || i_other->first > i_this->first) 494 // // return i_other; 495 // // } 496 // return i_this; 497 // } 498 // 499 // reverse_iterator rend() noexcept 500 // { 501 // reverse_iterator i_this = vlist::rend(); 502 // i_this.setLists(this, _p_other, false); 503 // // if(_p_other && !(*_p_other)->empty()) 504 // // { 505 // // reverse_iterator i_other = (*_p_other)->rend(); 506 // // i_other.setOtherList(_p_other, true); 507 // // if(vlist::empty() || i_other->first < i_this->first) 508 // // return i_other; 509 // // } 510 // return i_this; 511 // } 512 // 513 // const_reverse_iterator crend() const noexcept 514 // { 515 // const_reverse_iterator i_this = vlist::crend(); 516 // i_this.setLists(this, _p_other, false); 517 // // if(_p_other && !(*_p_other)->empty()) 518 // // { 519 // // const_reverse_iterator i_other = (*_p_other)->crend(); 520 // // i_other.setLists(this, _p_other, true); 521 // // if(vlist::empty() || i_other->first < i_this->first) 522 // // return i_other; 523 // // } 524 // return i_this; 525 // } 526 // 527 // bool empty() const noexcept 528 // { 529 // return vlist::empty() && (!_p_other || (*_p_other)->empty()); 530 // } 531 // 532 // size_type size() const noexcept 533 // { 534 // return vlist::size() + (_p_other ? (*_p_other)->size() : 0); 535 // } 536 // 537 // iterator find(const int& key) 538 // { 539 // iterator i_this = vlist::find(key); 540 // i_this.setLists(this, _p_other, false); 541 // if(i_this == vlist::end() && _p_other) 542 // { 543 // iterator i_other = (*_p_other)->find(key); 544 // i_other.setLists(this, _p_other, true); 545 // if(i_other != (*_p_other)->end()) 546 // return i_other; 547 // } 548 // return i_this; 549 // } 550 // 551 // const_iterator find(const int& key) const 552 // { 553 // const_iterator i_this = vlist::find(key); 554 // i_this.setLists(this, _p_other, false); 555 // if(i_this == vlist::end() && _p_other) 556 // { 557 // const MidiControllerList* mcl_other = *_p_other; 558 // const_iterator i_other = mcl_other->find(key); 559 // i_other.setLists(this, _p_other, true); 560 // if(i_other != mcl_other->end()) 561 // return i_other; 562 // } 563 // return i_this; 564 // } 565 // 566 // iterator lower_bound(const int& key) 567 // { 568 // iterator i_this = vlist::lower_bound(key); 569 // i_this.setLists(this, _p_other, false); 570 // if(i_this == vlist::end() && _p_other && !(*_p_other)->empty()) 571 // { 572 // iterator i_other = (*_p_other)->lower_bound(key); 573 // i_other.setLists(this, _p_other, true); 574 // if(i_other != (*_p_other)->end() && (vlist::empty() || i_other->first < i_this->first)) 575 // return i_other; 576 // } 577 // return i_this; 578 // } 579 // 580 // const_iterator lower_bound(const int& key) const 581 // { 582 // const_iterator i_this = vlist::lower_bound(key); 583 // i_this.setLists(this, _p_other, false); 584 // if(i_this == vlist::end() && _p_other && !(*_p_other)->empty()) 585 // { 586 // const MidiControllerList* mcl_other = *_p_other; 587 // const_iterator i_other = mcl_other->lower_bound(key); 588 // i_other.setLists(this, _p_other, true); 589 // if(i_other != mcl_other->end() && (vlist::empty() || i_other->first < i_this->first)) 590 // return i_other; 591 // } 592 // return i_this; 593 // } 594 // 595 // iterator upper_bound(const int& key) 596 // { 597 // iterator i_this = vlist::upper_bound(key); 598 // i_this.setLists(this, _p_other, false); 599 // if(i_this == vlist::end() && _p_other && !(*_p_other)->empty()) 600 // { 601 // iterator i_other = (*_p_other)->upper_bound(key); 602 // i_other.setLists(this, _p_other, true); 603 // if(i_other != (*_p_other)->end() && (vlist::empty() || i_other->first < i_this->first)) 604 // return i_other; 605 // } 606 // return i_this; 607 // } 608 // 609 // const_iterator upper_bound(const int& key) const 610 // { 611 // const_iterator i_this = vlist::upper_bound(key); 612 // i_this.setLists(this, _p_other, false); 613 // if(i_this == vlist::end() && _p_other && !(*_p_other)->empty()) 614 // { 615 // const MidiControllerList* mcl_other = *_p_other; 616 // const_iterator i_other = mcl_other->upper_bound(key); 617 // i_other.setLists(this, _p_other, true); 618 // if(i_other != mcl_other->end() && (vlist::empty() || i_other->first < i_this->first)) 619 // return i_other; 620 // } 621 // return i_this; 622 // } 623 // 624 // 625 // 626 // 627 // // // Returns an iterator that points to the inserted event. 628 // // // Note that the pair's key part is IGNORED. 629 // // // All information is gathered from the pair's value type T. 630 // // // Returns end() if an error occurred. 631 // // iCompoundMidiControllerList_t insert (const CompoundMidiControllerListInsertPair_t& v) 632 // // { 633 // // return add(v.second); 634 // // } 635 // // 636 // // // TODO: 637 // // // template <class P> iMixedPosList insert (P&& v) { return vlist::insert(v); } 638 // // // iMixedPosList insert (ciMixedPosList pos, const T& v) { return vlist::insert(pos, v); } 639 // // // template <class P> iMixedPosList insert (ciMixedPosList pos, P&& v) { return vlist::insert(pos, v); } 640 // // // template <class InputIterator> 641 // // // void insert (InputIterator first, InputIterator last) { return vlist::insert(first, last); } 642 // // // void insert (std::initializer_list<T> il) { return vlist::insert(il); } 643 // // 644 // // // Returns an iterator that points to the added event. 645 // // // Returns end() if an error occurred. 646 // // iMixedPosList_t add(const T& v) 647 // // { 648 // // const unsigned v_frame = v.frame(); 649 // // const unsigned v_tick = v.tick(); 650 // // ciMixedPosList_t pos = vlist::end(); 651 // // cMixedPosListRange_t r; 652 // // 653 // // // If list type is ticks, compare frame. If list type is frames, compare tick. 654 // // switch(type()) 655 // // { 656 // // case Pos::TICKS: 657 // // r = vlist::equal_range(v_tick); 658 // // for(pos = r.first; pos != r.second; ++pos) 659 // // if(v_frame < pos->second.frame()) 660 // // break; 661 // // return vlist::insert(pos, MixedPosListInsertPair_t(v_tick, v)); 662 // // break; 663 // // 664 // // case Pos::FRAMES: 665 // // r = vlist::equal_range(v_frame); 666 // // for(pos = r.first; pos != r.second; ++pos) 667 // // if(v_tick < pos->second.tick()) 668 // // break; 669 // // return vlist::insert(pos, MixedPosListInsertPair_t(v_frame, v)); 670 // // break; 671 // // } 672 // // return vlist::end(); 673 // // } 674 // 675 // 676 // }; 677 678 } // namespace MusECore 679 680 #endif 681 682