1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2009-2019 Werner Schweer 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License version 2 9 // as published by the Free Software Foundation and appearing in 10 // the file LICENCE.GPL 11 //============================================================================= 12 13 #ifndef __CHANGEMAP_H__ 14 #define __CHANGEMAP_H__ 15 16 #include <QMultiMap> 17 18 #include "fraction.h" 19 20 /** 21 \file 22 Definition of class ChangeMap. 23 */ 24 25 namespace Ms { 26 27 enum class ChangeMethod : signed char { 28 NORMAL, 29 EXPONENTIAL, 30 EASE_IN, 31 EASE_OUT, 32 EASE_IN_OUT // and shake it all about 33 }; 34 35 enum class ChangeDirection : signed char { 36 INCREASING, 37 DECREASING 38 }; 39 40 //--------------------------------------------------------- 41 /// ChangeEvent 42 /// item in ChangeMap 43 //--------------------------------------------------------- 44 45 enum class ChangeEventType : char { FIX, RAMP, INVALID }; 46 47 class ChangeEvent { 48 int value { 0 }; 49 ChangeEventType type { ChangeEventType::INVALID }; 50 Fraction length; 51 ChangeMethod method { ChangeMethod::NORMAL }; 52 ChangeDirection direction { ChangeDirection::INCREASING }; 53 int cachedStartVal { -1 }; 54 int cachedEndVal { -1 }; 55 56 public: ChangeEvent()57 ChangeEvent() {} ChangeEvent(int vel)58 ChangeEvent(int vel) : value(vel), type(ChangeEventType::FIX) {} ChangeEvent(Fraction s,Fraction e,int diff,ChangeMethod m,ChangeDirection d)59 ChangeEvent(Fraction s, Fraction e, int diff, ChangeMethod m, ChangeDirection d) 60 : value(diff), type(ChangeEventType::RAMP), length(e - s), method(m), direction(d) {} 61 62 bool operator==(const ChangeEvent& event) const; 63 bool operator!=(const ChangeEvent& event) const { return !(operator==(event)); } 64 65 friend class ChangeMap; 66 }; 67 68 //--------------------------------------------------------- 69 // ChangeMap 70 /// List of changes in a value. 71 //--------------------------------------------------------- 72 73 typedef std::vector<std::pair<Fraction, Fraction>> EndPointsVector; 74 75 class ChangeMap : public QMultiMap<Fraction, ChangeEvent> { 76 bool cleanedUp { false }; 77 static const int DEFAULT_VALUE { 80 }; // TODO 78 79 struct ChangeMethodItem { 80 ChangeMethod method; 81 const char* name; 82 }; 83 compareRampEvents(ChangeEvent & a,ChangeEvent & b)84 static bool compareRampEvents(ChangeEvent& a, ChangeEvent& b) { return a.length > b.length; } 85 86 void cleanupStage0(); 87 void cleanupStage1(); 88 void cleanupStage2(std::vector<bool>& startsInRamp, EndPointsVector& endPoints); 89 void cleanupStage3(); 90 91 public: ChangeMap()92 ChangeMap() {} 93 int val(Fraction tick); 94 std::vector<std::pair<Fraction, Fraction>> changesInRange(Fraction stick, Fraction etick); 95 96 void addFixed(Fraction tick, int value); 97 void addRamp(Fraction stick, Fraction etick, int change, ChangeMethod method, ChangeDirection direction); 98 void cleanup(); 99 100 void dump(); 101 102 static int interpolate(Fraction& eventTick, ChangeEvent& event, Fraction& tick); 103 static QString changeMethodToName(ChangeMethod method); 104 static ChangeMethod nameToChangeMethod(QString name); 105 106 static const std::vector<ChangeMethodItem> changeMethodTable; 107 }; 108 109 } // namespace Ms 110 #endif 111 112