MuseScore 3 源码分析之调号
音乐 刘宇帅 3年前 阅读量: 1942
enum Key 表示 调号类型,定义如下
enum class Key {
C_B = -7, // 7个降号
G_B, // 6个降号
D_B, // 5个降号
A_B, // 4个降号
E_B, // 3个降号
B_B, // 2个降号
F, // 1个降号
C, // 无升降号
G, // 1个升号
D, // 1个升号
A, // 1个升号
E, // 1个升号
B, // 1个升号
F_S, // 1个升号
C_S, // 1个升号
MIN = Key::C_B,
MAX = Key::C_S,
INVALID = Key::MIN - 1,
NUM_OF = Key::MAX - Key::MIN + 1,
DELTA_ENHARMONIC = 12
};
KeySigEvent 表示一个调号信息
class KeySigEvent {
Key _key { Key::INVALID }; // -7 -> +7
KeyMode _mode { KeyMode::UNKNOWN };
bool _custom { false };
bool _forInstrumentChange{ false };
QList<KeySym> _keySymbols;
void enforceLimits();
public:
KeySigEvent() {}
KeySigEvent(const KeySigEvent&);
bool operator==(const KeySigEvent& e) const;
bool operator!=(const KeySigEvent& e) const { return !(*this == e); }
void setKey(Key v);
void print() const;
Key key() const { return _key; }
KeyMode mode() const { return _mode; }
void setMode(KeyMode m) { _mode = m; }
bool custom() const { return _custom; }
void setCustom(bool val) { _custom = val; _key = Key::C; }
bool isValid() const { return _key != Key::INVALID; }
bool isAtonal() const { return _mode == KeyMode::NONE; }
void setForInstrumentChange(bool forInstrumentChange) { _forInstrumentChange = forInstrumentChange; }
bool forInstrumentChange() const{ return _forInstrumentChange; }
void initFromSubtype(int); // for backward compatibility
QList<KeySym>& keySymbols() { return _keySymbols; }
const QList<KeySym>& keySymbols() const { return _keySymbols; }
};
KeyList 用来保存 tick 的 调号信息,可以用查询某tick的调号
class KeyList : public std::map<const int, KeySigEvent> {
public:
KeyList() {}
KeySigEvent key(int tick) const;
KeySigEvent prevKey(int tick) const;
void setKey(int tick, KeySigEvent);
int nextKeyTick(int tick) const;
int currentKeyTick(int tick) const;
void read(XmlReader&, Score*);
};
}
Staff 里包含 KeyList
class Staff final : public ScoreElement {
public:
enum class HideMode { AUTO, ALWAYS, NEVER, INSTRUMENT };
private:
Part* _part { 0 };
ClefList clefs;
ClefTypeList _defaultClefType;
KeyList _keys;
调用 Staff::keySigEvent 获得调号
KeySigEvent Staff::keySigEvent(const Fraction& tick) const
{
return _keys.key(tick.ticks());
}