MuseScore/libmscore/note.h

534 lines
21 KiB
C
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
2012-11-19 10:08:15 +01:00
// Copyright (C) 2002-2012 Werner Schweer
2012-05-26 14:26:10 +02:00
//
// 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
2012-07-13 14:36:26 +02:00
Definition of classes Note and NoteHead.
2012-05-26 14:26:10 +02:00
*/
#include "element.h"
#include "symbol.h"
2012-11-19 10:08:15 +01:00
#include "noteevent.h"
2013-10-24 12:09:00 +02:00
#include "pitchspelling.h"
2016-01-04 14:48:58 +01:00
#include "shape.h"
#include "key.h"
2012-05-26 14:26:10 +02:00
2013-05-13 18:49:17 +02:00
namespace Ms {
2012-05-26 14:26:10 +02:00
class Tie;
class Chord;
class NoteEvent;
class Text;
class Score;
class Sym;
class MuseScoreView;
class Bend;
class AccidentalState;
class Accidental;
class NoteDot;
2012-09-12 16:19:03 +02:00
class Spanner;
2014-04-28 18:38:50 +02:00
class StaffType;
class NoteEditData;
enum class SymId;
2015-04-02 10:33:53 +02:00
enum class AccidentalType : char;
2012-05-26 14:26:10 +02:00
static const int MAX_DOTS = 4;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-07-25 11:49:34 +02:00
// @@ NoteHead
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
class NoteHead final : public Symbol {
Q_GADGET
2012-05-26 14:26:10 +02:00
public:
// keep in sync with noteHeadSchemeNames array in note.cpp
enum class Scheme : signed char {
///.\{
HEAD_AUTO = -1,
HEAD_NORMAL,
HEAD_PITCHNAME,
HEAD_PITCHNAME_GERMAN,
HEAD_SOLFEGE,
HEAD_SOLFEGE_FIXED,
HEAD_SHAPE_NOTE_4,
HEAD_SHAPE_NOTE_7_AIKIN,
HEAD_SHAPE_NOTE_7_FUNK,
HEAD_SHAPE_NOTE_7_WALKER,
HEAD_SCHEMES
///\}
};
// keep in sync with noteHeadGroupNames array in note.cpp
enum class Group : signed char {
2019-03-21 17:37:06 +01:00
///.\{
HEAD_NORMAL = 0,
HEAD_CROSS,
HEAD_PLUS,
HEAD_XCIRCLE,
HEAD_WITHX,
HEAD_TRIANGLE_UP,
HEAD_TRIANGLE_DOWN,
HEAD_SLASHED1,
HEAD_SLASHED2,
HEAD_DIAMOND,
HEAD_DIAMOND_OLD,
HEAD_CIRCLED,
HEAD_CIRCLED_LARGE,
HEAD_LARGE_ARROW,
HEAD_BREVIS_ALT,
HEAD_SLASH,
HEAD_SOL,
HEAD_LA,
HEAD_FA,
HEAD_MI,
HEAD_DO,
HEAD_RE,
HEAD_TI,
// not exposed from here
HEAD_DO_WALKER,
HEAD_RE_WALKER,
HEAD_TI_WALKER,
HEAD_DO_FUNK,
HEAD_RE_FUNK,
HEAD_TI_FUNK,
HEAD_DO_NAME,
HEAD_RE_NAME,
HEAD_MI_NAME,
HEAD_FA_NAME,
HEAD_SOL_NAME,
HEAD_LA_NAME,
HEAD_TI_NAME,
HEAD_SI_NAME,
HEAD_A_SHARP,
HEAD_A,
HEAD_A_FLAT,
HEAD_B_SHARP,
HEAD_B,
HEAD_B_FLAT,
HEAD_C_SHARP,
HEAD_C,
HEAD_C_FLAT,
HEAD_D_SHARP,
HEAD_D,
HEAD_D_FLAT,
HEAD_E_SHARP,
HEAD_E,
HEAD_E_FLAT,
HEAD_F_SHARP,
HEAD_F,
HEAD_F_FLAT,
HEAD_G_SHARP,
HEAD_G,
HEAD_G_FLAT,
HEAD_H,
HEAD_H_SHARP,
HEAD_CUSTOM,
HEAD_GROUPS,
HEAD_INVALID = -1
2019-03-21 17:37:06 +01:00
///\}
};
// keep in sync with noteHeadTypeNames array in note.cpp
enum class Type : signed char {
2019-03-21 17:37:06 +01:00
///.\{
HEAD_AUTO = -1,
HEAD_WHOLE = 0,
HEAD_HALF = 1,
HEAD_QUARTER = 2,
HEAD_BREVIS = 3,
HEAD_TYPES
2019-03-21 17:37:06 +01:00
///\}
};
Q_ENUM(Scheme);
Q_ENUM(Group);
Q_ENUM(Type);
NoteHead(Score* s = 0) : Symbol(s) {}
2014-06-27 13:41:49 +02:00
NoteHead &operator=(const NoteHead&) = delete;
2020-03-21 15:03:04 +01:00
NoteHead* clone() const override { return new NoteHead(*this); }
ElementType type() const override { return ElementType::NOTEHEAD; }
Group headGroup() const;
static QString scheme2userName(Scheme scheme);
static QString group2userName(Group group);
static QString type2userName(Type type);
static QString scheme2name(Scheme scheme);
static QString group2name(Group group);
static QString type2name(Type type);
static Scheme name2scheme(const QString& s);
static Group name2group(const QString& s);
static Type name2type(const QString& s);
};
//---------------------------------------------------------
// NoteVal
2019-03-21 17:37:06 +01:00
/// helper structure
/// \cond PLUGIN_API \private \endcond
//---------------------------------------------------------
struct NoteVal {
int pitch { -1 };
2014-09-22 14:31:28 +02:00
int tpc1 { Tpc::TPC_INVALID };
int tpc2 { Tpc::TPC_INVALID };
int fret { FRET_NONE };
int string { STRING_NONE };
NoteHead::Group headGroup { NoteHead::Group::HEAD_NORMAL };
NoteVal() {}
NoteVal(int p) : pitch(p) {}
2012-05-26 14:26:10 +02:00
};
2016-03-18 09:29:16 +01:00
static const int INVALID_LINE = -10000;
2012-08-12 11:44:36 +02:00
//---------------------------------------------------------------------------------------
2012-07-11 21:29:42 +02:00
// @@ Note
/// Graphic representation of a note.
2012-07-25 11:49:34 +02:00
//
// @P accidental Accidental note accidental (null if none)
// @P accidentalType int note accidental type
// @P dots array[NoteDot] list of note dots (some can be null, read only)
// @P dotsCount int number of note dots (read only)
// @P elements array[Element] list of elements attached to notehead
// @P fret int fret number in tablature
// @P ghost bool ghost note (guitar: death note)
// @P headScheme enum (NoteHeadScheme.HEAD_AUTO, .HEAD_NORMAL, .HEAD_PITCHNAME, .HEAD_PITCHNAME_GERMAN, .HEAD_SHAPE_NOTE_4, .HEAD_SHAPE_NOTE_7_AIKIN, .HEAD_SHAPE_NOTE_7_FUNK, .HEAD_SHAPE_NOTE_7_WALKER, .HEAD_SOLFEGE, .HEAD_SOLFEGE_FIXED)
// @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_SOL, .HEAD_TI, .HEAD_XCIRCLE, .HEAD_TRIANGLE)
// @P headType enum (NoteHeadType.HEAD_AUTO, .HEAD_BREVIS, .HEAD_HALF, .HEAD_QUARTER, .HEAD_WHOLE)
// @P hidden bool hidden, not played note (read only)
// @P line int notehead position (read only)
// @P mirror bool mirror notehead on x axis (read only)
// @P pitch int midi pitch
// @P play bool play note
// @P ppitch int actual played midi pitch (honoring ottavas) (read only)
// @P small bool small notehead
// @P string int string number in tablature
// @P subchannel int midi subchannel (for midi articulation) (read only)
// @P tieBack Tie note backward tie (null if none, read only)
// @P tieFor Tie note forward tie (null if none, read only)
// @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 tuning float tuning offset in cent
// @P userDotPosition enum (Direction.AUTO, Direction.DOWN, Direction.UP)
// @P userMirror enum (DirectionH.AUTO, DirectionH.LEFT, DirectionH.RIGHT)
// @P veloOffset int
// @P veloType enum (Note.OFFSET_VAL, Note.USER_VAL)
2012-08-12 11:44:36 +02:00
//---------------------------------------------------------------------------------------
2012-05-26 14:26:10 +02:00
class Note final : public Element {
Q_GADGET
public:
enum class ValueType : char { OFFSET_VAL, USER_VAL };
Q_ENUM(ValueType);
private:
2015-02-19 10:28:25 +01:00
bool _ghost { false }; ///< ghost note (guitar: death note)
bool _hidden { false }; ///< marks this note as the hidden one if there are
2015-02-19 10:28:25 +01:00
///< overlapping notes; hidden notes are not played
///< and heads + accidentals are not shown
bool _dotsHidden { false }; ///< dots of hidden notes are hidden too
///< except if only one note is dotted
bool _fretConflict { false }; ///< used by TAB staves to mark a fretting conflict:
///< two or more notes on the same string
2015-02-19 10:28:25 +01:00
bool dragMode { false };
bool _mirror { false }; ///< True if note is mirrored at stem.
bool _small { false };
bool _play { true }; // note is not played if false
mutable bool _mark { false }; // for use in sequencer
bool _fixed { false }; // for slash notation
MScore::DirectionH _userMirror { MScore::DirectionH::AUTO }; ///< user override of mirror
Direction _userDotPosition { Direction::AUTO }; ///< user override of dot position
2015-02-19 10:28:25 +01:00
NoteHead::Scheme _headScheme { NoteHead::Scheme::HEAD_AUTO };
2015-02-19 10:28:25 +01:00
NoteHead::Group _headGroup { NoteHead::Group::HEAD_NORMAL };
NoteHead::Type _headType { NoteHead::Type::HEAD_AUTO };
ValueType _veloType { ValueType::OFFSET_VAL };
2015-11-02 14:09:03 +01:00
char _offTimeType { 0 }; // compatibility only 1 - user(absolute), 2 - offset (%)
char _onTimeType { 0 }; // compatibility only 1 - user, 2 - offset
int _subchannel { 0 }; ///< articulation
2016-03-18 09:29:16 +01:00
int _line { INVALID_LINE }; ///< y-Position; 0 - top line.
2015-11-02 14:09:03 +01:00
int _fret { -1 }; ///< for tablature view
int _string { -1 };
mutable int _tpc[2] { Tpc::TPC_INVALID, Tpc::TPC_INVALID }; ///< tonal pitch class (concert/transposing)
mutable int _pitch { 0 }; ///< Note pitch as midi value (0 - 127).
2015-02-19 10:28:25 +01:00
int _veloOffset { 0 }; ///< velocity user offset in percent, or absolute velocity for this note
int _fixedLine { 0 }; // fixed line number if _fixed == true
qreal _tuning { 0.0 }; ///< pitch offset in cent, playable only by internal synthesizer
Accidental* _accidental { 0 };
2012-05-26 14:26:10 +02:00
2015-02-19 10:28:25 +01:00
Tie* _tieFor { 0 };
Tie* _tieBack { 0 };
2012-05-26 14:26:10 +02:00
2016-02-06 22:03:43 +01:00
ElementList _el; ///< fingering, other text, symbols or images
QVector<NoteDot*> _dots;
2012-11-19 10:08:15 +01:00
NoteEventList _playEvents;
2016-02-06 22:03:43 +01:00
QVector<Spanner*> _spannerFor;
QVector<Spanner*> _spannerBack;
2012-05-26 14:26:10 +02:00
SymId _cachedNoteheadSym; // use in draw to avoid recomputing at every update
SymId _cachedSymNull; // additional symbol for some transparent notehead
QString _fretString;
void startDrag(EditData&) override;
QRectF drag(EditData&ed) override;
void endDrag(EditData&) override;
void editDrag(EditData &editData) override;
void verticalDrag(EditData& ed);
void horizontalDrag(EditData& ed);
2012-09-12 16:19:03 +02:00
void addSpanner(Spanner*);
void removeSpanner(Spanner*);
int concertPitchIdx() const;
2014-04-22 17:02:03 +02:00
void updateRelLine(int relLine, bool undoable);
bool isNoteName() const;
SymId noteHead() const;
2012-09-12 16:19:03 +02:00
void normalizeLeftDragDelta(Segment* seg, EditData &ed, NoteEditData* ned);
public:
2012-05-26 14:26:10 +02:00
Note(Score* s = 0);
2014-07-10 18:59:44 +02:00
Note(const Note&, bool link = false);
2012-05-26 14:26:10 +02:00
~Note();
2014-07-10 18:59:44 +02:00
Note& operator=(const Note&) = delete;
virtual Note* clone() const override { return new Note(*this, false); }
2017-01-18 14:16:33 +01:00
ElementType type() const override { return ElementType::NOTE; }
2013-05-28 15:42:02 +02:00
2020-03-21 15:03:04 +01:00
void undoUnlink() override;
2020-03-21 15:03:04 +01:00
qreal mag() const override;
2013-05-28 15:42:02 +02:00
2020-03-21 15:03:04 +01:00
void layout() override;
2012-05-26 14:26:10 +02:00
void layout2();
//setter is used only in drumset tools to setup the notehead preview in the drumset editor and the palette
void setCachedNoteheadSym(SymId i) { _cachedNoteheadSym = i; };
2020-03-21 15:03:04 +01:00
void scanElements(void* data, void (*func)(void*, Element*), bool all = true) override;
void setTrack(int val) override;
2012-05-26 14:26:10 +02:00
int playTicks() const;
qreal headWidth() const;
qreal headHeight() const;
qreal tabHeadWidth(const StaffType* tab = 0) const;
qreal tabHeadHeight(const StaffType* tab = 0) const;
QPointF stemDownNW() const;
QPointF stemUpSE() const;
qreal bboxXShift() const;
qreal noteheadCenterX() const;
qreal bboxRightPos() const;
qreal headBodyWidth() const;
2013-01-02 09:29:17 +01:00
NoteHead::Scheme headScheme() const { return _headScheme; }
NoteHead::Group headGroup() const { return _headGroup; }
NoteHead::Type headType() const { return _headType; }
void setHeadScheme(NoteHead::Scheme val);
void setHeadGroup(NoteHead::Group val);
void setHeadType(NoteHead::Type t);
2012-05-26 14:26:10 +02:00
2020-03-21 15:03:04 +01:00
int subtype() const override { return int(_headGroup); }
QString subtypeName() const override;
2012-05-26 14:26:10 +02:00
void setPitch(int val);
void setPitch(int pitch, int tpc1, int tpc2);
int pitch() const { return _pitch; }
int ottaveCapoFret() const;
int ppitch() const; ///< playback pitch
int epitch() const; ///< effective pitch
2012-11-19 10:08:15 +01:00
qreal tuning() const { return _tuning; }
void setTuning(qreal v) { _tuning = v; }
void undoSetTpc(int v);
int transposition() const;
bool fixed() const { return _fixed; }
void setFixed(bool v) { _fixed = v; }
int fixedLine() const { return _fixedLine; }
void setFixedLine(int v) { _fixedLine = v; }
int tpc() const;
int tpc1() const { return _tpc[0]; } // non transposed tpc
int tpc2() const { return _tpc[1]; } // transposed tpc
2016-02-04 17:06:32 +01:00
QString tpcUserName(bool explicitAccidental = false) const;
2012-05-26 14:26:10 +02:00
void setTpc(int v);
void setTpc1(int v) { _tpc[0] = v; }
void setTpc2(int v) { _tpc[1] = v; }
2012-05-26 14:26:10 +02:00
void setTpcFromPitch();
2014-04-10 13:13:37 +02:00
int tpc1default(int pitch) const;
int tpc2default(int pitch) const;
2014-04-14 10:39:27 +02:00
int transposeTpc(int tpc);
2012-05-26 14:26:10 +02:00
Accidental* accidental() const { return _accidental; }
2012-11-19 10:08:15 +01:00
void setAccidental(Accidental* a) { _accidental = a; }
2014-09-22 14:31:28 +02:00
2015-04-03 18:23:51 +02:00
AccidentalType accidentalType() const;
2015-04-02 10:33:53 +02:00
void setAccidentalType(AccidentalType type);
2012-05-26 14:26:10 +02:00
int line() const;
2016-12-23 12:05:18 +01:00
void setLine(int n) { _line = n; }
int physicalLine() const;
2012-05-26 14:26:10 +02:00
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; }
2020-03-21 15:03:04 +01:00
void add(Element*) override;
void remove(Element*) override;
2012-05-26 14:26:10 +02:00
bool mirror() const { return _mirror; }
void setMirror(bool val) { _mirror = val; }
bool small() const { return _small; }
2013-01-02 09:29:17 +01:00
void setSmall(bool val);
2012-05-26 14:26:10 +02:00
bool play() const { return _play; }
void setPlay(bool val) { _play = val; }
Ms::Tie* tieFor() const { return _tieFor; }
Ms::Tie* tieBack() const { return _tieBack; }
2012-05-26 14:26:10 +02:00
void setTieFor(Tie* t) { _tieFor = t; }
void setTieBack(Tie* t) { _tieBack = t; }
Note* firstTiedNote() const;
const Note* lastTiedNote() const;
Note* lastTiedNote() { return const_cast<Note*>(static_cast<const Note*>(this)->lastTiedNote()); }
int unisonIndex() const;
void disconnectTiedNotes();
void connectTiedNotes();
2012-05-26 14:26:10 +02:00
Chord* chord() const { return (Chord*)parent(); }
void setChord(Chord* a) { setParent((Element*)a); }
2020-03-21 15:03:04 +01:00
void draw(QPainter*) const override;
2012-05-26 14:26:10 +02:00
2020-03-21 15:03:04 +01:00
void read(XmlReader&) override;
bool readProperties(XmlReader&) override;
void readAddConnector(ConnectorInfoReader* info, bool pasteMode) override;
void write(XmlWriter&) const override;
2012-05-26 14:26:10 +02:00
2017-03-31 13:03:15 +02:00
bool acceptDrop(EditData&) const override;
2020-03-21 15:03:04 +01:00
Element* drop(EditData&) override;
2012-05-26 14:26:10 +02:00
2013-01-02 09:29:17 +01:00
bool hidden() const { return _hidden; }
void setHidden(bool val) { _hidden = val; }
bool dotsHidden() const { return _dotsHidden; }
void setDotsHidden(bool val) { _dotsHidden = val; }
2012-05-26 14:26:10 +02:00
NoteType noteType() const;
2016-02-04 17:06:32 +01:00
QString noteTypeUserName() const;
2012-05-26 14:26:10 +02:00
2017-01-16 20:51:12 +01:00
ElementList& el() { return _el; }
const ElementList& el() const { return _el; }
2012-05-26 14:26:10 +02:00
2013-01-02 09:29:17 +01:00
int subchannel() const { return _subchannel; }
void setSubchannel(int val) { _subchannel = val; }
2012-05-26 14:26:10 +02:00
MScore::DirectionH userMirror() const { return _userMirror; }
void setUserMirror(MScore::DirectionH d) { _userMirror = d; }
2012-05-26 14:26:10 +02:00
2016-03-02 13:20:19 +01:00
Direction userDotPosition() const { return _userDotPosition; }
void setUserDotPosition(Direction d) { _userDotPosition = d; }
2012-05-26 14:26:10 +02:00
bool dotIsUp() const; // actual dot position
2020-03-21 15:03:04 +01:00
void reset() override;
2012-05-26 14:26:10 +02:00
2014-05-07 18:09:01 +02:00
ValueType veloType() const { return _veloType; }
void setVeloType(ValueType v) { _veloType = v; }
2013-01-02 09:29:17 +01:00
int veloOffset() const { return _veloOffset; }
void setVeloOffset(int v) { _veloOffset = v; }
2012-05-26 14:26:10 +02:00
2012-11-19 10:08:15 +01:00
void setOnTimeOffset(int v);
void setOffTimeOffset(int v);
2012-05-26 14:26:10 +02:00
int customizeVelocity(int velo) const;
2017-01-16 20:51:12 +01:00
NoteDot* dot(int n) { return _dots[n]; }
2016-02-06 22:03:43 +01:00
const QVector<NoteDot*>& dots() const { return _dots; }
QVector<NoteDot*>& dots() { return _dots; }
2016-01-04 14:48:58 +01:00
2015-03-19 10:39:18 +01:00
int qmlDotsCount();
2012-05-26 14:26:10 +02:00
void updateAccidental(AccidentalState*);
void updateLine();
void setNval(const NoteVal&, Fraction = { -1, 1} );
2012-11-19 10:08:15 +01:00
NoteEventList& playEvents() { return _playEvents; }
const NoteEventList& playEvents() const { return _playEvents; }
NoteEvent* noteEvent(int idx) { return &_playEvents[idx]; }
void setPlayEvents(const NoteEventList& l) { _playEvents = l; }
2012-05-26 14:26:10 +02:00
2016-02-06 22:03:43 +01:00
const QVector<Spanner*>& spannerFor() const { return _spannerFor; }
const QVector<Spanner*>& spannerBack() const { return _spannerBack; }
void addSpannerBack(Spanner* e) { if (!_spannerBack.contains(e)) _spannerBack.push_back(e); }
2013-06-10 11:03:34 +02:00
bool removeSpannerBack(Spanner* e) { return _spannerBack.removeOne(e); }
void addSpannerFor(Spanner* e) { if (!_spannerFor.contains(e)) _spannerFor.push_back(e); }
2013-06-10 11:03:34 +02:00
bool removeSpannerFor(Spanner* e) { return _spannerFor.removeOne(e); }
2012-09-12 16:19:03 +02:00
void transposeDiatonic(int interval, bool keepAlterations, bool useDoubleAccidentals);
2020-03-21 15:03:04 +01:00
void localSpatiumChanged(qreal oldValue, qreal newValue) override;
QVariant getProperty(Pid propertyId) const override;
bool setProperty(Pid propertyId, const QVariant&) override;
void undoChangeDotsVisible(bool v);
2020-03-21 15:03:04 +01:00
QVariant propertyDefault(Pid) const override;
QString propertyUserValue(Pid) const override;
2013-02-20 17:53:15 +01:00
2013-06-10 11:03:34 +02:00
bool mark() const { return _mark; }
void setMark(bool v) const { _mark = v; }
2020-03-21 15:03:04 +01:00
void setScore(Score* s) override;
2016-03-02 13:20:19 +01:00
void setDotY(Direction);
2014-08-13 21:01:21 +02:00
2017-01-31 19:30:49 +01:00
void addParentheses();
2013-11-25 15:42:40 +01:00
static SymId noteHead(int direction, NoteHead::Group, NoteHead::Type, int tpc, Key key, NoteHead::Scheme scheme);
static SymId noteHead(int direction, NoteHead::Group, NoteHead::Type);
NoteVal noteVal() const;
Element* nextInEl(Element* e);
Element* prevInEl(Element* e);
2020-03-21 15:03:04 +01:00
Element* nextElement() override;
Element* prevElement() override;
virtual Element* lastElementBeforeSegment();
2020-03-21 15:03:04 +01:00
Element* nextSegmentElement() override;
Element* prevSegmentElement() override;
2016-02-04 17:06:32 +01:00
2020-03-21 15:03:04 +01:00
QString accessibleInfo() const override;
QString screenReaderInfo() const override;
QString accessibleExtraInfo() const override;
2016-01-04 14:48:58 +01:00
2020-03-21 15:03:04 +01:00
Shape shape() const override;
2016-03-19 11:41:38 +01:00
std::vector<Note*> tiedNotes() const;
2016-09-22 12:02:27 +02:00
void setOffTimeType(int v) { _offTimeType = v; }
void setOnTimeType(int v) { _onTimeType = v; }
int offTimeType() const { return _offTimeType; }
int onTimeType() const { return _onTimeType; }
};
2012-05-26 14:26:10 +02:00
2013-05-13 18:49:17 +02:00
} // namespace Ms
2012-05-26 14:26:10 +02:00
#endif