-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
note.h
435 lines (354 loc) · 17.7 KB
/
note.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2012 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __NOTE_H__
#define __NOTE_H__
/**
\file
Definition of classes Note and NoteHead.
*/
#include "element.h"
#include "symbol.h"
#include "noteevent.h"
#include "pitchspelling.h"
class QPainter;
namespace Ms {
class Tie;
class Chord;
class NoteEvent;
class Text;
class Score;
class Sym;
class MuseScoreView;
class Bend;
class AccidentalState;
class Accidental;
class NoteDot;
class Spanner;
class StaffType;
enum class SymId;
static const int MAX_DOTS = 3;
//---------------------------------------------------------
// @@ NoteHead
//---------------------------------------------------------
class NoteHead : public Symbol {
Q_OBJECT
public:
enum class Group : signed char {
HEAD_NORMAL = 0,
HEAD_CROSS,
HEAD_DIAMOND,
HEAD_TRIANGLE,
HEAD_MI,
HEAD_SLASH,
HEAD_XCIRCLE,
HEAD_DO,
HEAD_RE,
HEAD_FA,
HEAD_LA,
HEAD_TI,
HEAD_SOL,
HEAD_BREVIS_ALT,
HEAD_GROUPS,
HEAD_INVALID = -1
};
enum class Type : signed char {
HEAD_AUTO = -1,
HEAD_WHOLE = 0,
HEAD_HALF = 1,
HEAD_QUARTER = 2,
HEAD_BREVIS = 3,
HEAD_TYPES
};
NoteHead(Score* s) : Symbol(s) {}
NoteHead &operator=(const NoteHead&) = delete;
virtual NoteHead* clone() const { return new NoteHead(*this); }
virtual Element::Type type() const { return Element::Type::NOTEHEAD; }
virtual void write(Xml& xml) const;
Group headGroup() const;
static const char* groupToGroupName(Group group);
};
//---------------------------------------------------------
// NoteVal
// helper structure
//---------------------------------------------------------
struct NoteVal {
int pitch { -1 };
int tpc { Tpc::TPC_INVALID };
int fret { FRET_NONE };
int string { STRING_NONE };
NoteHead::Group headGroup { NoteHead::Group::HEAD_NORMAL };
NoteVal() {}
NoteVal(int p) : pitch(p) {}
};
//---------------------------------------------------------------------------------------
// @@ Note
/// Graphic representation of a note.
//
// @P subchannel int midi subchannel (for midi articulation) (read only)
// @P line int notehead position (read only)
// @P fret int fret number in tablature
// @P string int string number in tablature
// @P tpc int tonal pitch class, as per concert pitch setting
// @P tpc1 int tonal pitch class, non transposed
// @P tpc2 int tonal pitch class, transposed
// @P pitch int midi pitch
// @P ppitch int actual played midi pitch (honoring ottavas) (read only)
// @P ghost bool ghost note (guitar: death note)
// @P hidden bool hidden, not played note (read only)
// @P mirror bool mirror note head on x axis (read only)
// @P small bool small note head
// @P play bool play note
// @P tuning qreal tuning offset in cent
// @P veloType Ms::Note::ValueType (OFFSET_VAL, USER_VAL)
// @P veloOffset int
// @P userMirror Ms::MScore::DirectionH (AUTO, LEFT, RIGHT)
// @P userDotPosition Ms::MScore::Direction (AUTO, UP, DOWN)
// @P headGroup Ms::NoteHead::Group (HEAD_NORMAL, HEAD_CROSS, HEAD_DIAMOND, HEAD_TRIANGLE, HEAD_MI, HEAD_SLASH, HEAD_XCIRCLE, HEAD_DO, HEAD_RE, HEAD_FA, HEAD_LA, HEAD_TI, HEAD_SOL, HEAD_BREVIS_ALT)
// @P headType Ms::NoteHead::Type (HEAD_AUTO, HEAD_WHOLE, HEAD_HALF, HEAD_QUARTER, HEAD_BREVIS)
// @P elements array[Ms::Element] list of elements attached to note head
// @P accidental Ms::Accidental note accidental (null if none)
// @P dots array[Ms::NoteDot] list of note dots (empty if none)
// @P tieFor Ms::Tie note forward tie (null if none, read only)
// @P tieBack Ms::Tie note backward tie (null if none, read only)
//---------------------------------------------------------------------------------------
class Note : public Element {
Q_OBJECT
Q_PROPERTY(int subchannel READ subchannel)
Q_PROPERTY(int line READ line)
Q_PROPERTY(int fret READ fret WRITE undoSetFret)
Q_PROPERTY(int string READ string WRITE undoSetString)
Q_PROPERTY(int tpc READ tpc)
Q_PROPERTY(int tpc1 READ tpc1 WRITE undoSetTpc1)
Q_PROPERTY(int tpc2 READ tpc2 WRITE undoSetTpc2)
Q_PROPERTY(int pitch READ pitch WRITE undoSetPitch)
Q_PROPERTY(int ppitch READ ppitch)
Q_PROPERTY(bool ghost READ ghost WRITE undoSetGhost)
Q_PROPERTY(bool hidden READ hidden)
Q_PROPERTY(bool mirror READ mirror)
Q_PROPERTY(bool small READ small WRITE undoSetSmall)
Q_PROPERTY(bool play READ play WRITE undoSetPlay)
Q_PROPERTY(qreal tuning READ tuning WRITE undoSetTuning)
Q_PROPERTY(Ms::Note::ValueType veloType READ veloType WRITE undoSetVeloType)
Q_PROPERTY(int veloOffset READ veloOffset WRITE undoSetVeloOffset)
Q_PROPERTY(Ms::MScore::DirectionH userMirror READ userMirror WRITE undoSetUserMirror)
Q_PROPERTY(Ms::MScore::Direction userDotPosition READ userDotPosition WRITE undoSetUserDotPosition)
Q_PROPERTY(Ms::NoteHead::Group headGroup READ headGroup WRITE undoSetHeadGroup)
Q_PROPERTY(Ms::NoteHead::Type headType READ headType WRITE undoSetHeadType)
Q_PROPERTY(QQmlListProperty<Ms::Element> elements READ qmlElements)
Q_PROPERTY(Ms::Accidental* accidental READ accidental)
Q_PROPERTY(QQmlListProperty<Ms::NoteDot> dots READ qmlDots)
Q_PROPERTY(Ms::Tie* tieFor READ tieFor)
Q_PROPERTY(Ms::Tie* tieBack READ tieBack)
Q_ENUMS(ValueType)
Q_ENUMS(Ms::NoteHead::Group)
Q_ENUMS(Ms::NoteHead::Type)
Q_ENUMS(Ms::MScore::Direction)
Q_ENUMS(Ms::MScore::DirectionH)
public:
enum class ValueType : char { OFFSET_VAL, USER_VAL };
private:
int _subchannel; ///< articulation
int _line; ///< y-Position; 0 - top line.
int _fret; ///< for tablature view
int _string;
mutable int _tpc[2]; ///< tonal pitch class (concert/transposing)
mutable int _pitch; ///< Note pitch as midi value (0 - 127).
bool _ghost; ///< ghost note (guitar: death note)
bool _hidden; ///< markes this note as the hidden one if there are
///< overlapping notes; hidden notes are not played
///< and heads + accidentals are not shown
bool _dotsHidden; ///< dots of hidden notes are hidden too
///< except if only one note is dotted
bool _fretConflict; ///< used by TAB staves to mark a fretting conflict:
///< two or mor enotes on the same string
bool dragMode;
bool _mirror; ///< True if note is mirrored at stem.
bool _small;
bool _play; // note is not played if false
mutable bool _mark; // for use in sequencer
MScore::DirectionH _userMirror; ///< user override of mirror
MScore::Direction _userDotPosition; ///< user override of dot position
NoteHead::Group _headGroup;
NoteHead::Type _headType;
ValueType _veloType;
short int _veloOffset; ///< velocity user offset in percent, or absolute velocity for this note
qreal _tuning; ///< pitch offset in cent, playable only by internal synthesizer
Accidental* _accidental;
ElementList _el; ///< fingering, other text, symbols or images
Tie* _tieFor;
Tie* _tieBack;
NoteDot* _dots[MAX_DOTS];
NoteEventList _playEvents;
int _offTimeType = 0; // compatibility only 1 - user(absolute), 2 - offset (%)
int _onTimeType = 0; // compatibility only 1 - user, 2 - offset
int _lineOffset; ///< Used during mouse dragging.
QList<Spanner*> _spannerFor;
QList<Spanner*> _spannerBack;
virtual QRectF drag(EditData*) override;
void endDrag();
void endEdit();
void addSpanner(Spanner*);
void removeSpanner(Spanner*);
int concertPitchIdx() const;
void updateRelLine(int relLine, bool undoable);
public:
Note(Score* s = 0);
Note(const Note&, bool link = false);
~Note();
Note& operator=(const Note&) = delete;
virtual Note* clone() const { return new Note(*this, false); }
Element::Type type() const { return Element::Type::NOTE; }
virtual qreal mag() const;
QPointF pagePos() const; ///< position in page coordinates
QPointF canvasPos() const; ///< position in page coordinates
void layout();
void layout2();
void layout10(AccidentalState*);
void scanElements(void* data, void (*func)(void*, Element*), bool all=true);
void setTrack(int val);
int playTicks() const;
qreal headWidth() const;
qreal headHeight() const;
qreal tabHeadWidth(StaffType* tab = 0) const;
qreal tabHeadHeight(StaffType* tab = 0) const;
QPointF attach() const;
SymId noteHead() const;
NoteHead::Group headGroup() const { return _headGroup; }
NoteHead::Type headType() const { return _headType; }
void setHeadGroup(NoteHead::Group val);
void setHeadType(NoteHead::Type t);
virtual int subtype() const { return (int) _headGroup; }
virtual QString subtypeName() const;
void setPitch(int val);
void undoSetPitch(int val);
void setPitch(int pitch, int tpc1, int tpc2);
int pitch() const { return _pitch; }
int ppitch() const; ///< playback pitch
int epitch() const; ///< effective pitch
qreal tuning() const { return _tuning; }
void setTuning(qreal v) { _tuning = v; }
void undoSetTpc(int v);
int transposition() const;
int tpc() const;
int tpc1() const { return _tpc[0]; } // non transposed tpc
int tpc2() const { return _tpc[1]; } // transposed tpc
void setTpc(int v);
void setTpc1(int v) { _tpc[0] = v; }
void setTpc2(int v) { _tpc[1] = v; }
void setTpcFromPitch();
int tpc1default(int pitch) const;
int tpc2default(int pitch) const;
void undoSetTpc1(int tpc) { undoChangeProperty(P_ID::TPC1, tpc); }
void undoSetTpc2(int tpc) { undoChangeProperty(P_ID::TPC2, tpc); }
int transposeTpc(int tpc);
Accidental* accidental() const { return _accidental; }
void setAccidental(Accidental* a) { _accidental = a; }
int line() const { return _line + _lineOffset; }
void setLine(int n);
int fret() const { return _fret; }
void setFret(int val) { _fret = val; }
int string() const { return _string; }
void setString(int val);
bool ghost() const { return _ghost; }
void setGhost(bool val) { _ghost = val; }
bool fretConflict() const { return _fretConflict; }
void setFretConflict(bool val) { _fretConflict = val; }
virtual void add(Element*);
virtual void remove(Element*);
bool mirror() const { return _mirror; }
void setMirror(bool val) { _mirror = val; }
bool small() const { return _small; }
void setSmall(bool val);
bool play() const { return _play; }
void setPlay(bool val) { _play = val; }
Ms::Tie* tieFor() const { return _tieFor; }
Ms::Tie* tieBack() const { return _tieBack; }
void setTieFor(Tie* t) { _tieFor = t; }
void setTieBack(Tie* t) { _tieBack = t; }
Chord* chord() const { return (Chord*)parent(); }
void setChord(Chord* a) { setParent((Element*)a); }
void draw(QPainter*) const;
void read(XmlReader&);
void write(Xml& xml) const;
bool acceptDrop(MuseScoreView*, const QPointF&, Element*) const;
Element* drop(const DropData&);
bool hidden() const { return _hidden; }
void setHidden(bool val) { _hidden = val; }
bool dotsHidden() const { return _dotsHidden; }
void setDotsHidden(bool val) { _dotsHidden = val; }
NoteType noteType() const;
ElementList el() { return _el; }
const ElementList el() const { return _el; }
QQmlListProperty<Ms::Element> qmlElements() { return QQmlListProperty<Ms::Element>(this, _el); }
int subchannel() const { return _subchannel; }
void setSubchannel(int val) { _subchannel = val; }
MScore::DirectionH userMirror() const { return _userMirror; }
void setUserMirror(MScore::DirectionH d) { _userMirror = d; }
MScore::Direction userDotPosition() const { return _userDotPosition; }
void setUserDotPosition(MScore::Direction d) { _userDotPosition = d; }
bool dotIsUp() const; // actual dot position
void reset();
ValueType veloType() const { return _veloType; }
void setVeloType(ValueType v) { _veloType = v; }
int veloOffset() const { return _veloOffset; }
void setVeloOffset(int v) { _veloOffset = v; }
void setOnTimeOffset(int v);
void setOffTimeOffset(int v);
int customizeVelocity(int velo) const;
NoteDot* dot(int n) { return _dots[n]; }
QQmlListProperty<Ms::NoteDot> qmlDots();
void updateAccidental(AccidentalState*);
void updateLine();
void setNval(const NoteVal&);
NoteEventList& playEvents() { return _playEvents; }
const NoteEventList& playEvents() const { return _playEvents; }
NoteEvent* noteEvent(int idx) { return &_playEvents[idx]; }
void setPlayEvents(const NoteEventList& l) { _playEvents = l; }
QList<Spanner*> spannerFor() const { return _spannerFor; }
QList<Spanner*> spannerBack() const { return _spannerBack; }
void addSpannerBack(Spanner* e) { _spannerBack.push_back(e); }
bool removeSpannerBack(Spanner* e) { return _spannerBack.removeOne(e); }
void addSpannerFor(Spanner* e) { _spannerFor.push_back(e); }
bool removeSpannerFor(Spanner* e) { return _spannerFor.removeOne(e); }
void transposeDiatonic(int interval, bool keepAlterations, bool useDoubleAccidentals);
void undoSetFret(int);
void undoSetString(int);
void undoSetGhost(bool);
void undoSetMirror(bool);
void undoSetSmall(bool);
void undoSetPlay(bool);
void undoSetTuning(qreal);
void undoSetVeloType(ValueType);
void undoSetVeloOffset(int);
void undoSetOnTimeUserOffset(int);
void undoSetOffTimeUserOffset(int);
void undoSetUserMirror(MScore::DirectionH);
void undoSetUserDotPosition(MScore::Direction);
void undoSetHeadGroup(NoteHead::Group);
void undoSetHeadType(NoteHead::Type);
virtual QVariant getProperty(P_ID propertyId) const;
virtual bool setProperty(P_ID propertyId, const QVariant&);
virtual QVariant propertyDefault(P_ID) const;
bool mark() const { return _mark; }
void setMark(bool v) const { _mark = v; }
virtual void setScore(Score* s);
void setDotY(MScore::Direction);
void addBracket();
static SymId noteHead(int direction, NoteHead::Group, NoteHead::Type);
NoteVal noteVal() const;
};
// extern const SymId noteHeads[2][int(NoteHead::Group::HEAD_GROUPS)][int(NoteHead::Type::HEAD_TYPES)];
} // namespace Ms
Q_DECLARE_METATYPE(Ms::NoteHead::Group);
Q_DECLARE_METATYPE(Ms::NoteHead::Type);
Q_DECLARE_METATYPE(Ms::Note::ValueType);
#endif