1 /* 2 * Note.h - declaration of class note which contains all informations about a 3 * note + definitions of several constants and enums 4 * 5 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net> 6 * 7 * This file is part of LMMS - https://lmms.io 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of 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 GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public 20 * License along with this program (see COPYING); if not, write to the 21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301 USA. 23 * 24 */ 25 26 #ifndef NOTE_H 27 #define NOTE_H 28 29 #include <QtCore/QVector> 30 31 #include "volume.h" 32 #include "panning.h" 33 #include "MidiTime.h" 34 #include "SerializingObject.h" 35 36 class DetuningHelper; 37 38 39 enum Keys 40 { 41 Key_C = 0, 42 Key_CIS = 1, Key_DES = 1, 43 Key_D = 2, 44 Key_DIS = 3, Key_ES = 3, 45 Key_E = 4, Key_FES = 4, 46 Key_F = 5, 47 Key_FIS = 6, Key_GES = 6, 48 Key_G = 7, 49 Key_GIS = 8, Key_AS = 8, 50 Key_A = 9, 51 Key_AIS = 10, Key_B = 10, 52 Key_H = 11 53 } ; 54 55 56 enum Octaves 57 { 58 Octave_0, 59 Octave_1, 60 Octave_2, 61 Octave_3, 62 Octave_4, DefaultOctave = Octave_4, 63 Octave_5, 64 Octave_6, 65 Octave_7, 66 Octave_8, 67 NumOctaves 68 } ; 69 70 71 const int WhiteKeysPerOctave = 7; 72 const int BlackKeysPerOctave = 5; 73 const int KeysPerOctave = WhiteKeysPerOctave + BlackKeysPerOctave; 74 const int NumKeys = NumOctaves * KeysPerOctave; 75 const int DefaultKey = DefaultOctave*KeysPerOctave + Key_A; 76 77 const float MaxDetuning = 4 * 12.0f; 78 79 80 81 class EXPORT Note : public SerializingObject 82 { 83 public: 84 Note( const MidiTime & length = MidiTime( 0 ), 85 const MidiTime & pos = MidiTime( 0 ), 86 int key = DefaultKey, 87 volume_t volume = DefaultVolume, 88 panning_t panning = DefaultPanning, 89 DetuningHelper * detuning = NULL ); 90 Note( const Note & note ); 91 virtual ~Note(); 92 93 // used by GUI setSelected(const bool selected)94 inline void setSelected( const bool selected ) { m_selected = selected; } setOldKey(const int oldKey)95 inline void setOldKey( const int oldKey ) { m_oldKey = oldKey; } setOldPos(const MidiTime & oldPos)96 inline void setOldPos( const MidiTime & oldPos ) { m_oldPos = oldPos; } 97 setOldLength(const MidiTime & oldLength)98 inline void setOldLength( const MidiTime & oldLength ) 99 { 100 m_oldLength = oldLength; 101 } setIsPlaying(const bool isPlaying)102 inline void setIsPlaying( const bool isPlaying ) 103 { 104 m_isPlaying = isPlaying; 105 } 106 107 108 void setLength( const MidiTime & length ); 109 void setPos( const MidiTime & pos ); 110 void setKey( const int key ); 111 virtual void setVolume( volume_t volume ); 112 virtual void setPanning( panning_t panning ); 113 void quantizeLength( const int qGrid ); 114 void quantizePos( const int qGrid ); 115 lessThan(const Note * lhs,const Note * rhs)116 static inline bool lessThan( const Note * lhs, const Note * rhs ) 117 { 118 // function to compare two notes - must be called explictly when 119 // using qSort 120 if( (int)( *lhs ).pos() < (int)( *rhs ).pos() ) 121 { 122 return true; 123 } 124 else if( (int)( *lhs ).pos() > (int)( *rhs ).pos() ) 125 { 126 return false; 127 } 128 return ( (int)( *lhs ).key() > (int)( *rhs ).key() ); 129 } 130 selected()131 inline bool selected() const 132 { 133 return m_selected; 134 } 135 oldKey()136 inline int oldKey() const 137 { 138 return m_oldKey; 139 } 140 oldPos()141 inline MidiTime oldPos() const 142 { 143 return m_oldPos; 144 } 145 oldLength()146 inline MidiTime oldLength() const 147 { 148 return m_oldLength; 149 } 150 isPlaying()151 inline bool isPlaying() const 152 { 153 return m_isPlaying; 154 } 155 endPos()156 inline MidiTime endPos() const 157 { 158 const int l = length(); 159 return pos() + l; 160 } 161 length()162 inline const MidiTime & length() const 163 { 164 return m_length; 165 } 166 pos()167 inline const MidiTime & pos() const 168 { 169 return m_pos; 170 } 171 pos(MidiTime basePos)172 inline MidiTime pos( MidiTime basePos ) const 173 { 174 const int bp = basePos; 175 return m_pos - bp; 176 } 177 key()178 inline int key() const 179 { 180 return m_key; 181 } 182 getVolume()183 inline volume_t getVolume() const 184 { 185 return m_volume; 186 } 187 midiVelocity(int midiBaseVelocity)188 int midiVelocity( int midiBaseVelocity ) const 189 { 190 return qMin( MidiMaxVelocity, getVolume() * midiBaseVelocity / DefaultVolume ); 191 } 192 getPanning()193 inline panning_t getPanning() const 194 { 195 return m_panning; 196 } 197 classNodeName()198 static QString classNodeName() 199 { 200 return "note"; 201 } 202 nodeName()203 inline virtual QString nodeName() const 204 { 205 return classNodeName(); 206 } 207 208 static MidiTime quantized( const MidiTime & m, const int qGrid ); 209 detuning()210 DetuningHelper * detuning() const 211 { 212 return m_detuning; 213 } 214 bool hasDetuningInfo() const; 215 bool withinRange(int tickStart, int tickEnd) const; 216 217 void createDetuning(); 218 219 220 protected: 221 virtual void saveSettings( QDomDocument & doc, QDomElement & parent ); 222 virtual void loadSettings( const QDomElement & _this ); 223 224 225 private: 226 // for piano roll editing 227 bool m_selected; 228 int m_oldKey; 229 MidiTime m_oldPos; 230 MidiTime m_oldLength; 231 bool m_isPlaying; 232 233 int m_key; 234 volume_t m_volume; 235 panning_t m_panning; 236 MidiTime m_length; 237 MidiTime m_pos; 238 DetuningHelper * m_detuning; 239 }; 240 241 242 typedef QVector<Note *> NoteVector; 243 244 245 #endif 246