Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
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, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include "containers.h"
26 :
27 : #include "engravingitem.h"
28 : #include "interval.h"
29 : #include "noteevent.h"
30 : #include "noteval.h"
31 : #include "pitchspelling.h"
32 : #include "symbol.h"
33 : #include "tie.h"
34 : #include "tiejumppointlist.h"
35 :
36 : namespace mu::engraving {
37 : class Accidental;
38 : class AccidentalState;
39 : class Chord;
40 : class Factory;
41 : class NoteDot;
42 : class NoteEditData;
43 : class Score;
44 : class Spanner;
45 : class StaffType;
46 : class Text;
47 : class Tie;
48 : class Transaction;
49 : enum class AccidentalType : unsigned char;
50 : enum class NoteType : unsigned char;
51 : struct NoteParenthesisInfo;
52 :
53 : static constexpr int MAX_DOTS = 4;
54 :
55 : //--------------------------------------------------------------------------------
56 : // LINE ATTACHMENT POINT
57 : // Represents the attachment point of any line (tie, slur, glissando...)
58 : // with respect to the note. Each note can hold a vector of line attach points, which
59 : // it may use to make spacing decision with the surrounding items.
60 : //--------------------------------------------------------------------------------
61 : class LineAttachPoint
62 : {
63 : public:
64 12167 : LineAttachPoint(EngravingItem* l, double x, double y, bool start)
65 12167 : : m_line(l), m_pos(PointF(x, y)), m_start(start) {}
66 :
67 101242 : const EngravingItem* line() const { return m_line; }
68 14902 : const PointF pos() const { return m_pos; }
69 8695 : bool start() const { return m_start; }
70 :
71 : private:
72 : EngravingItem* m_line = nullptr;
73 : PointF m_pos = PointF(0.0, 0.0);
74 : bool m_start = true;
75 : };
76 :
77 : //---------------------------------------------------------
78 : // @@ NoteHead
79 : //---------------------------------------------------------
80 :
81 : class NoteHead final : public Symbol
82 : {
83 0 : OBJECT_ALLOCATOR(engraving, NoteHead)
84 1429 : DECLARE_CLASSOF(ElementType::NOTEHEAD)
85 :
86 : public:
87 : NoteHead(DummyParentOr<Note> parent);
88 0 : NoteHead(const NoteHead&) = default;
89 : NoteHead& operator=(const NoteHead&) = delete;
90 0 : NoteHead* clone() const override { return new NoteHead(*this); }
91 :
92 : NoteHeadGroup headGroup() const;
93 : };
94 :
95 : static const int INVALID_LINE = -10000;
96 :
97 : //---------------------------------------------------------------------------------------
98 : // @@ Note
99 : /// Graphic representation of a note.
100 : //
101 : // @P accidental Accidental note accidental (null if none)
102 : // @P accidentalType int note accidental type
103 : // @P dots array[NoteDot] list of note dots (some can be null, read only)
104 : // @P dotsCount int number of note dots (read only)
105 : // @P elements array[EngravingItem] list of elements attached to notehead
106 : // @P fret int fret number in tablature
107 : // @P ghost bool ghost note (guitar: death note)
108 : // @P headScheme enum (NoteHeadScheme.HEAD_AUTO, .HEAD_NORMAL, .HEAD_PITCHNAME, .HEAD_PITCHNAME_NO_ACCIDENTALS, .HEAD_PITCHNAME_GERMAN, .HEAD_PITCHNAME_GERMAN_NO_ACCIDENTALS, .HEAD_SHAPE_NOTE_4, .HEAD_SHAPE_NOTE_7_AIKIN, .HEAD_SHAPE_NOTE_7_FUNK, .HEAD_SHAPE_NOTE_7_WALKER, .HEAD_SOLFEGE, .HEAD_SOLFEGE_FIXED)
109 : // @P headGroup enum (NoteHeadGroup.HEAD_NORMAL, .HEAD_BREVIS_ALT, .HEAD_CROSS, .HEAD_DIAMOND, .HEAD_DO, .HEAD_FA, .HEAD_LA, .HEAD_MI, .HEAD_RE, .HEAD_SLASH, .HEAD_LARGE_DIAMOND, .HEAD_SOL, .HEAD_TI, .HEAD_XCIRCLE, .HEAD_TRIANGLE)
110 : // @P headType enum (NoteHeadType.HEAD_AUTO, .HEAD_BREVIS, .HEAD_HALF, .HEAD_QUARTER, .HEAD_WHOLE)
111 : // @P hidden bool hidden, not played note (read only)
112 : // @P line int notehead position (read only)
113 : // @P mirror bool mirror notehead on x axis (read only)
114 : // @P pitch int midi pitch
115 : // @P play bool play note
116 : // @P ppitch int actual played midi pitch (honoring ottavas) (read only)
117 : // @P isSmall bool small notehead
118 : // @P string int string number in tablature
119 : // @P subchannel int midi subchannel (for midi articulation) (read only)
120 : // @P tieBack Tie note backward tie (null if none, read only)
121 : // @P tieFor Tie note forward tie (null if none, read only)
122 : // @P tpc int tonal pitch class, as per concert pitch setting
123 : // @P tpc1 int tonal pitch class, non transposed
124 : // @P tpc2 int tonal pitch class, transposed
125 : // @P tuning float tuning offset in cent
126 : // @P userDotPosition enum (Direction.AUTO, Direction.DOWN, Direction.UP)
127 : // @P userMirror enum (DirectionH.AUTO, DirectionH.LEFT, DirectionH.RIGHT)
128 : // @P veloOffset int
129 : // @P veloType enum (Note.OFFSET_VAL, Note.USER_VAL)
130 : //---------------------------------------------------------------------------------------
131 :
132 : class Note final : public EngravingItem
133 : {
134 78681 : OBJECT_ALLOCATOR(engraving, Note)
135 3855 : DECLARE_CLASSOF(ElementType::NOTE)
136 :
137 : public:
138 : enum class SlideType : unsigned char {
139 : Undefined = 0,
140 : UpToNote,
141 : DownToNote,
142 : UpFromNote,
143 : DownFromNote
144 : };
145 :
146 : enum DisplayFretOption : signed char {
147 : Hide = -1,
148 : NoHarmonic,
149 : NaturalHarmonic,
150 : ArtificialHarmonic
151 : };
152 :
153 : ~Note();
154 :
155 : std::vector<Note*> compoundNotes() const;
156 :
157 : Note& operator=(const Note&) = delete;
158 329 : virtual Note* clone() const override { return new Note(*this, false); }
159 :
160 21948955 : Chord* chord() const { return (Chord*)ownershipParent(); }
161 : void setOwnershipParent(DummyParentOr<Chord> ch);
162 :
163 : void undoUnlink() override;
164 :
165 : double mag() const override;
166 : EngravingItem* elementBase() const override;
167 :
168 : void scanElements(std::function<void(EngravingItem*)> func) override;
169 : void setTrack(track_idx_t val) override;
170 :
171 : staff_idx_t vStaffIdx() const override;
172 :
173 : int playTicks() const;
174 : Fraction playTicksFraction() const;
175 :
176 : double headWidth() const;
177 : double headHeight() const;
178 : double tabHeadWidth(const StaffType* tab = 0) const;
179 : double tabHeadHeight(const StaffType* tab = 0) const;
180 : PointF stemDownNW() const;
181 : PointF stemUpSE() const;
182 : double bboxXShift() const;
183 : double noteheadCenterX() const;
184 : double bboxRightPos() const;
185 : double headBodyWidth() const;
186 : double outsideTieAttachX(bool up) const;
187 :
188 52737 : NoteHeadScheme headScheme() const { return m_headScheme; }
189 : void updateHeadGroup(const NoteHeadGroup headGroup);
190 115840 : NoteHeadGroup headGroup() const { return m_headGroup; }
191 38426 : NoteHeadType headType() const { return m_headType; }
192 : void setHeadScheme(NoteHeadScheme val);
193 : void setHeadGroup(NoteHeadGroup val);
194 : void setHeadType(NoteHeadType t);
195 :
196 0 : int subtype() const override { return int(m_headGroup); }
197 : TranslatableString subtypeUserName() const override;
198 :
199 : void setPitch(int val, bool notifyAboutChanged = true);
200 : void setPitch(int pitch, int tpc1, int tpc2);
201 91586 : int pitch() const { return m_pitch; }
202 :
203 30153 : double centOffset() const { return m_centOffset; }
204 4787 : void setCentOffset(double v) { m_centOffset = v; }
205 0 : int quarterToneOffset() const { return std::round(m_centOffset / 50); }
206 :
207 : int ottaveCapoFret() const;
208 : int linkedOttavaPitchOffset() const;
209 : int ppitch() const; // playback pitch
210 : int epitch() const; // effective pitch
211 : int octave() const;
212 : int playingOctave() const;
213 28664 : double tuning() const { return m_tuning; }
214 4939 : void setTuning(double v) { m_tuning = v; }
215 : double playingTuning() const;
216 : void undoSetTpc(int v);
217 : int transposition() const;
218 1433693 : bool fixed() const { return m_fixed; }
219 164 : void setFixed(bool v) { m_fixed = v; }
220 23924 : int fixedLine() const { return m_fixedLine; }
221 164 : void setFixedLine(int v) { m_fixedLine = v; }
222 :
223 : int tpc() const;
224 10233 : int tpc1() const { return m_tpc[0]; } // non transposed tpc
225 6240 : int tpc2() const { return m_tpc[1]; } // transposed tpc
226 : String tpcUserName(bool explicitAccidental = false, bool full = false) const;
227 :
228 : void setTpc(int v);
229 39305 : void setTpc1(int v) { m_tpc[0] = v; }
230 40592 : void setTpc2(int v) { m_tpc[1] = v; }
231 : void setTpcFromPitch(Prefer prefer = Prefer::NEAREST);
232 : int tpc1default(int pitch) const;
233 : int tpc2default(int pitch) const;
234 : int transposeTpc(int tpc) const;
235 :
236 : int playingTpc() const;
237 :
238 321002 : Accidental* accidental() const { return m_accidental; }
239 : void setAccidental(Accidental* a) { m_accidental = a; }
240 :
241 : AccidentalType accidentalType() const;
242 : void setAccidentalType(AccidentalType type);
243 :
244 : int line() const;
245 59205 : void setLine(int n) { m_line = n; }
246 :
247 43038 : int fret() const { return m_fret; }
248 4839 : void setFret(int val) { m_fret = val; }
249 0 : float harmonicFret() const { return m_harmonicFret; }
250 74 : void setHarmonicFret(float val) { m_harmonicFret = val; }
251 503 : int harmonicPitchOffset() const { return m_harmonicPitchOffset; }
252 74 : void setHarmonicPitchOffset(int val) { m_harmonicPitchOffset = val; }
253 10713 : DisplayFretOption displayFret() const { return m_displayFret; }
254 74 : void setDisplayFret(DisplayFretOption val) { m_displayFret = val; }
255 378922 : String fretString() const { return m_fretString; }
256 1395 : void setFretString(const String& s) { m_fretString = s; }
257 : bool negativeFretUsed() const;
258 54397 : int string() const { return m_string; }
259 4783 : void setString(int val) { m_string = val; }
260 : int stringOrLine() const;
261 :
262 147598 : bool ghost() const { return m_ghost; }
263 2210 : void setGhost(bool val) { m_ghost = val; }
264 143560 : bool deadNote() const { return m_deadNote; }
265 2955 : void setDeadNote(bool deadNote) { m_deadNote = deadNote; }
266 :
267 12 : bool fretConflict() const { return m_fretConflict; }
268 2057 : void setFretConflict(bool val) { m_fretConflict = val; }
269 :
270 : void add(EngravingItem*) override;
271 : void remove(EngravingItem*) override;
272 :
273 38430 : bool isSmall() const { return m_isSmall; }
274 : void setSmall(bool val);
275 :
276 28489 : bool play() const { return m_play; }
277 5437 : void setPlay(bool val) { m_play = val; }
278 :
279 : GuitarBend* bendFor() const;
280 : GuitarBend* bendBack() const;
281 : GuitarBend* diveFor() const;
282 : GuitarBend* diveBack() const;
283 658670 : Tie* tieFor() const { return m_tieFor; }
284 401597 : Tie* tieBack() const { return m_tieBack; }
285 : Tie* tieForNonPartial() const;
286 : Tie* tieBackNonPartial() const;
287 : LaissezVib* laissezVib() const;
288 : PartialTie* incomingPartialTie() const;
289 : PartialTie* outgoingPartialTie() const;
290 : void setTieFor(Tie* t);
291 : void setTieBack(Tie* t);
292 : Note* firstTiedNote(bool ignorePlayback = true) const;
293 : Note* lastTiedNote(bool ignorePlayback = true) const;
294 :
295 : int unisonIndex() const;
296 : void disconnectTiedNotes();
297 : void connectTiedNotes();
298 :
299 : void setupAfterRead(const Fraction& tick, bool pasteMode);
300 :
301 : bool acceptDrop(EditData&) const override;
302 : EngravingItem* drop(Transaction& tx, EditData&) override;
303 :
304 111127 : bool hidden() const { return m_hidden; }
305 58930 : void setHidden(bool val) { m_hidden = val; }
306 712 : bool dotsHidden() const { return m_dotsHidden; }
307 58963 : void setDotsHidden(bool val) { m_dotsHidden = val; }
308 :
309 : NoteType noteType() const;
310 : String noteTypeUserName() const;
311 :
312 249806 : ElementList& el() { return m_el; }
313 162030 : const ElementList& el() const { return m_el; }
314 :
315 972 : int subchannel() const { return m_subchannel; }
316 20778 : void setSubchannel(int val) { m_subchannel = val; }
317 :
318 82516 : DirectionH userMirror() const { return m_userMirror; }
319 10 : void setUserMirror(DirectionH d) { m_userMirror = d; }
320 :
321 82610 : DirectionV userDotPosition() const { return m_userDotPosition; }
322 10 : void setUserDotPosition(DirectionV d) { m_userDotPosition = d; }
323 684 : DirectionV dotPosition() const { return m_dotPosition; }
324 58946 : void setDotPosition(DirectionV d) { m_dotPosition = d; }
325 : bool dotIsUp() const; // actual dot position
326 :
327 : void reset() override;
328 :
329 : float userVelocityFraction() const;
330 29660 : int userVelocity() const { return m_userVelocity; }
331 1073 : void setUserVelocity(int v) { m_userVelocity = v; }
332 :
333 : void setOnTimeOffset(int v);
334 : void setOffTimeOffset(int v);
335 :
336 : int customizeVelocity(int velo) const;
337 4 : NoteDot* dot(int n) { return m_dots.at(n); }
338 148348 : const std::vector<NoteDot*>& dots() const { return m_dots; }
339 134199 : std::vector<NoteDot*>& dots() { return m_dots; }
340 :
341 : void updateAccidental(AccidentalState*);
342 : void updateLine();
343 : void setNval(const NoteVal&, Fraction = { -1, 1 });
344 16 : NoteEventList& playEvents() { return m_playEvents; }
345 620 : const NoteEventList& playEvents() const { return m_playEvents; }
346 : NoteEvent* noteEvent(int idx) { return &m_playEvents[idx]; }
347 455 : void setPlayEvents(const NoteEventList& l) { m_playEvents = l; }
348 :
349 458437 : const std::vector<Spanner*>& spannerFor() const { return m_spannerFor; }
350 427088 : const std::vector<Spanner*>& spannerBack() const { return m_spannerBack; }
351 :
352 577 : void addSpannerBack(Spanner* e)
353 : {
354 577 : if (!muse::contains(m_spannerBack, e)) {
355 577 : m_spannerBack.push_back(e);
356 : }
357 577 : }
358 :
359 0 : bool removeSpannerBack(Spanner* e) { return muse::remove(m_spannerBack, e); }
360 577 : void addSpannerFor(Spanner* e)
361 : {
362 577 : if (!muse::contains(m_spannerFor, e)) {
363 577 : m_spannerFor.push_back(e);
364 : }
365 577 : }
366 :
367 0 : bool removeSpannerFor(Spanner* e) { return muse::remove(m_spannerFor, e); }
368 :
369 : bool transposeDiatonic(int interval, bool keepAlterations, bool useDoubleAccidentals);
370 : bool transpose(Interval interval, bool useDoubleSharpsFlats);
371 :
372 : void localSpatiumChanged(double oldValue, double newValue) override;
373 : PropertyValue getProperty(Pid propertyId) const override;
374 : bool setProperty(Pid propertyId, const PropertyValue&) override;
375 : PropertyValue propertyDefault(Pid) const override;
376 : void styleChanged() override;
377 :
378 0 : bool mark() const { return m_mark; }
379 0 : void setMark(bool v) const { m_mark = v; }
380 : void setScore(Score* s) override;
381 :
382 : static SymId noteHead(int direction, NoteHeadGroup, NoteHeadType, int tpc, Key key, NoteHeadScheme scheme);
383 : static SymId noteHead(int direction, NoteHeadGroup, NoteHeadType);
384 : NoteVal noteVal() const;
385 :
386 : EngravingItem* nextInEl(EngravingItem* e);
387 : EngravingItem* prevInEl(EngravingItem* e);
388 : EngravingItem* nextElement() override;
389 : EngravingItem* prevElement() override;
390 : EngravingItem* lastElementBeforeSegment();
391 : EngravingItem* nextSegmentElement() override;
392 : EngravingItem* prevSegmentElement() override;
393 :
394 : String accessibleInfo() const override;
395 : String screenReaderInfo() const override;
396 : String accessibleExtraInfo() const override;
397 :
398 : std::vector<Note*> tiedNotes() const;
399 :
400 0 : void setOffTimeType(int v) { m_offTimeType = v; }
401 0 : void setOnTimeType(int v) { m_onTimeType = v; }
402 0 : int offTimeType() const { return m_offTimeType; }
403 0 : int onTimeType() const { return m_onTimeType; }
404 :
405 : void attachSlide(SlideType slideType);
406 :
407 : bool hasSlideToNote() const;
408 : bool hasSlideFromNote() const;
409 492 : SlideType slideToType() const { return m_slideToType; }
410 9 : SlideType slideFromType() const { return m_slideFromType; }
411 :
412 : void setParenthesesMode(const ParenthesesMode& v, bool addToLinked = true, bool generated = false) override;
413 :
414 : const NoteParenthesisInfo* parenthesisInfo() const;
415 :
416 78 : void setHarmonic(bool val) { m_harmonic = val; }
417 118328 : bool harmonic() const { return m_harmonic; }
418 :
419 : bool isGrace() const;
420 :
421 : bool isPreBendOrDiveStart() const;
422 : bool isGraceBendStart() const;
423 : bool isContinuationOfBend() const;
424 :
425 : bool hasAnotherStraightAboveOrBelow(bool above) const;
426 :
427 62024 : std::vector<LineAttachPoint>& lineAttachPoints() { return m_lineAttachPoints; }
428 403777 : const std::vector<LineAttachPoint>& lineAttachPoints() const { return m_lineAttachPoints; }
429 6013 : void addStartLineAttachPoint(PointF point, EngravingItem* line) { addLineAttachPoint(point, line, true); }
430 6154 : void addEndLineAttachPoint(PointF point, EngravingItem* line) { addLineAttachPoint(point, line, false); }
431 :
432 : PointF posInStaffCoordinates();
433 :
434 105778 : bool isTrillCueNote() const { return m_isTrillCueNote; }
435 : void setIsTrillCueNote(bool v);
436 :
437 : SymId noteHead() const;
438 : bool isNoteName() const;
439 :
440 : void updateFrettingForTiesAndBends();
441 : bool shouldHideFret() const;
442 : bool shouldForceShowFret() const;
443 :
444 : void setVisible(bool v) override;
445 :
446 23675 : bool overrideBendVisibilityRules() const { return m_overrideBendVisibilityRules; }
447 79 : void setOverrideBendVisibilityRules(bool v) { m_overrideBendVisibilityRules = v; }
448 :
449 95 : bool hideGeneratedParens() const { return m_hideGeneratedParens; }
450 55 : void setHideGeneratedParens(bool v) { m_hideGeneratedParens = v; }
451 :
452 35725 : TieJumpPointList* tieJumpPoints() { return &m_jumpPoints; }
453 4 : const TieJumpPointList* tieJumpPoints() const { return &m_jumpPoints; }
454 :
455 : bool isExactUnison(Note* other);
456 :
457 : struct LayoutData : public EngravingItem::LayoutData {
458 : ld_field<bool> useTablature = { "[Note] useTablature", false };
459 : ld_field<SymId> cachedNoteheadSym = { "[Note] cachedNoteheadSym", SymId::noSym }; // use in draw to avoid recomputing at every update
460 : ld_field<SymId> cachedSymNull = { "[Note] cachedSymNull", SymId::noSym }; // additional symbol for some transparent notehead
461 : ld_field<bool> mirror = { "[Note] mirror", false }; // True if note is mirrored at stem.
462 : ld_field<bool> hasGeneratedParens = { "[Note] hasGeneratedParens", false }; // Should generated parens be created
463 : };
464 1122817 : DECLARE_LAYOUTDATA_METHODS(Note)
465 :
466 : private:
467 :
468 : friend class Factory;
469 : Note(DummyParentOr<Chord> ch);
470 : Note(const Note&, bool link = false);
471 :
472 : void startDrag(EditData&) override;
473 : RectF drag(EditData& ed) override;
474 : void endDrag(EditData&) override;
475 :
476 : void dragInEditMode(EditData& ed);
477 : void verticalDrag(EditData& ed);
478 : void horizontalDrag(EditData& ed);
479 :
480 : void addSpanner(Spanner*);
481 : void removeSpanner(Spanner*);
482 : int concertPitchIdx() const;
483 : void updateRelLine(int absLine, bool undoable);
484 :
485 : static std::vector<Note*> findTiedNotes(Note* startNote, bool followPartialTies = true);
486 :
487 : void normalizeLeftDragDelta(Segment* seg, EditData& ed, NoteEditData* ned);
488 :
489 : void getNoteListForDots(std::vector<Note*>& topDownNotes, std::vector<Note*>& bottomUpNotes, std::vector<int>& anchoredDots);
490 :
491 : void addLineAttachPoint(PointF point, EngravingItem* line, bool start);
492 :
493 : bool m_ghost = false; // ghost note
494 : bool m_deadNote = false; // dead note
495 :
496 : bool m_isTrillCueNote = false;
497 :
498 : bool m_hidden = false; // marks this note as the hidden one if there are
499 : // overlapping notes; hidden notes are not played
500 : // and heads + accidentals are not shown
501 : bool m_dotsHidden = false; // dots of hidden notes are hidden too
502 : // except if only one note is dotted
503 : bool m_fretConflict = false; // used by TAB staves to mark a fretting conflict:
504 : // two or more notes on the same string
505 : bool m_isSmall = false;
506 : bool m_play = true; // note is not played if false
507 : mutable bool m_mark = false; // for use in sequencer
508 : bool m_fixed = false; // for slash notation
509 :
510 : bool m_overrideBendVisibilityRules = false;
511 :
512 : bool m_hideGeneratedParens = false;
513 :
514 : SlideType m_slideToType = SlideType::Undefined;
515 : SlideType m_slideFromType = SlideType::Undefined;
516 :
517 : DirectionH m_userMirror = DirectionH::AUTO; ///< user override of mirror
518 : DirectionV m_userDotPosition = DirectionV::AUTO; ///< user override of dot position
519 : DirectionV m_dotPosition = DirectionV::AUTO; // used as an intermediate step when resolving dot conflicts
520 :
521 : NoteHeadScheme m_headScheme = NoteHeadScheme::HEAD_AUTO;
522 : NoteHeadGroup m_headGroup = NoteHeadGroup::HEAD_NORMAL;
523 : NoteHeadType m_headType = NoteHeadType::HEAD_AUTO;
524 :
525 : VeloType m_veloType = VeloType::USER_VAL;
526 :
527 : int m_offTimeType = 0; // compatibility only 1 - user(absolute), 2 - offset (%)
528 : int m_onTimeType = 0; // compatibility only 1 - user, 2 - offset
529 :
530 : int m_subchannel = 0; // articulation
531 : int m_line = INVALID_LINE; // y-Position; 0 - top line.
532 : int m_fret = -1; // for tablature view
533 : float m_harmonicFret = -1.0;
534 : int m_harmonicPitchOffset = 0;
535 : DisplayFretOption m_displayFret = DisplayFretOption::NoHarmonic;
536 : int m_string = -1;
537 : mutable int m_tpc[2] = { Tpc::TPC_INVALID, Tpc::TPC_INVALID }; // tonal pitch class (concert/transposing)
538 : mutable int m_pitch = 0; // Note pitch as midi value (0 - 127).
539 : mutable double m_centOffset = 0.0; // Pitch offset in cents (100 cents = 1 semitone)
540 :
541 : int m_userVelocity = 0; // velocity user offset in percent, or absolute velocity for this note
542 : int m_fixedLine = 0; // fixed line number if _fixed == true
543 : double m_tuning = 0.0; // pitch offset in cent, playable only by internal synthesizer
544 :
545 : Accidental* m_accidental = nullptr;
546 :
547 : Tie* m_tieFor = nullptr;
548 : Tie* m_tieBack = nullptr;
549 :
550 : bool m_harmonic = false;
551 :
552 : bool m_hasParens = false;
553 :
554 : ElementList m_el; // fingering, other text, symbols or images
555 : std::vector<NoteDot*> m_dots;
556 : NoteEventList m_playEvents;
557 : std::vector<Spanner*> m_spannerFor;
558 : std::vector<Spanner*> m_spannerBack;
559 :
560 : String m_fretString;
561 :
562 : std::vector<LineAttachPoint> m_lineAttachPoints;
563 : TieJumpPointList m_jumpPoints { this };
564 : };
565 : } // namespace mu::engraving
|