MuseScore 3 源码分析之 Segment
音乐 刘宇帅 3年前 阅读量: 1266
每个小节被分成多个 Segment,Segment 包含所有开始时间点相同的元素,且 Segment 是有类型的,所以一个 Segment 里的元素类型也是相同的。
SegmentType 定义
enum class SegmentType {
///.\{
Invalid = 0x0,
BeginBarLine = 0x1, // 开始小节线
HeaderClef = 0x2, // 曲谱开头 谱号
KeySig = 0x4, // 调号
Ambitus = 0x8, // 音域
TimeSig = 0x10, // 拍号
StartRepeatBarLine = 0x20, // 反复开始小节线
Clef = 0x40, // 谱号
BarLine = 0x80, // 小节线
Breath = 0x100, // 呼吸记号
//--
ChordRest = 0x200, // 音符/休止符
//--
EndBarLine = 0x400, // 结束小节线
KeySigAnnounce = 0x800,
TimeSigAnnounce = 0x1000,
All = -1, ///< Includes all barline types
/// Alias for `BeginBarLine | StartRepeatBarLine | BarLine | EndBarLine`
BarLineType = BeginBarLine | StartRepeatBarLine | BarLine | EndBarLine
///\}
};
Segment 定义
class Segment final : public Element {
SegmentType _segmentType { SegmentType::Invalid }; // 类型
Fraction _tick; // { Fraction(0, 1) }; // segment 在曲谱整体开始tick比例信息
Fraction _ticks; // { Fraction(0, 1) }; // 当前 segment 的时值信息
Spatium _extraLeadingSpace;
qreal _stretch;
Segment* _next = nullptr; // linked list of segments inside a measure
Segment* _prev = nullptr;
std::vector<Element*> _annotations;
std::vector<Element*> _elist; // Element storage, size = staves * VOICES.
std::vector<Shape> _shapes; // size = staves
std::vector<qreal> _dotPosX; // size = staves
....
....
如果 Segment 类型是 Segment::ChordRest,那么可以遍历 _elist 里的各个声部,每个声部就包含一个和弦下的所有音(单个音符也会保存在一个ChordRest中)
SegmentList 用来保存一组 Segment,定义如下
class SegmentList {
Segment* _first; ///< First item of segment list
Segment* _last; ///< Last item of segment list
int _size; ///< Number of items in segment list
....
....
Measure 中就是保留了一个 SegmentList,其中包含了该小节下所有的 Segment