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