Skip to content

Commit

Permalink
Replacd integer midi tick values by fractions.
Browse files Browse the repository at this point in the history
- tick names a position on the time axis
- tick is always a Fraction()
- only Measure() and Segment() (and Tuplet?) have a tick value
- tick() for an generic element return only a sensible value if isMeasure() or isSegment() or isSegment(parent())

- "ticks" names a duration stored in a Fraction()
- the tick value for an Segment is relative to its measure

- rename "duration" to "ticks"
- rename afrac() to tick()
- rename rfrac() to rtick()
- rename some variables, changing "fraction" into "tick"
  (example: actualFraction() into actualTicks())

- Lyrics ticks are written as Fraction, on read if xmlreader sees a "/" it reads a fraction
  else midi ticks for backwards compatibility
  • Loading branch information
wschweer committed Feb 18, 2019
1 parent 6469ea4 commit ec3be9a
Show file tree
Hide file tree
Showing 239 changed files with 3,639 additions and 4,383 deletions.
4 changes: 2 additions & 2 deletions libmscore/ambitus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ void Ambitus::layout()
qreal _spatium = spatium();
Staff* stf = nullptr;
if (segm && track() > -1) {
int tick = segm->tick();
Fraction tick = segm->tick();
stf = score()->staff(staffIdx());
lineDist = stf->lineDistance(tick) * _spatium;
numOfLines = stf->lines(tick);
Expand Down Expand Up @@ -453,7 +453,7 @@ void Ambitus::draw(QPainter* p) const

// draw ledger lines (if not in a palette)
if (segment() && track() > -1) {
int tick = segment()->tick();
Fraction tick = segment()->tick();
Staff* stf = score()->staff(staffIdx());
qreal lineDist = stf->lineDistance(tick);
int numOfLines = stf->lines(tick);
Expand Down
13 changes: 6 additions & 7 deletions libmscore/barline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static void undoChangeBarLineType(BarLine* bl, BarLineType barType)
}
}
else if (segmentType == SegmentType::BeginBarLine) {
Segment* segment1 = m->undoGetSegmentR(SegmentType::BeginBarLine, 0);
Segment* segment1 = m->undoGetSegmentR(SegmentType::BeginBarLine, Fraction(0, 1));
for (Element* e : segment1->elist()) {
if (e) {
e->score()->undo(new ChangeProperty(e, Pid::BARLINE_TYPE, QVariant::fromValue(barType), PropertyFlags::NOSTYLE));
Expand Down Expand Up @@ -303,7 +303,7 @@ void BarLine::getY() const
// after skipping ones with hideSystemBarLine set
// and accounting for staves that are shown but have invisible measures

int tick = segment()->measure()->tick();
Fraction tick = segment()->measure()->tick();
const StaffType* st1 = staff1->staffType(tick);

int from = _spanFrom;
Expand Down Expand Up @@ -343,8 +343,7 @@ void BarLine::drawDots(QPainter* painter, qreal x) const
y2l = 2.5 * _spatium;
}
else {
Staff* staff = score()->staff(staffIdx());
const StaffType* st = staff->staffType(tick());
const StaffType* st = staffType();

//workaround to make new Bravura font work correctly with repeatDots
qreal offset = score()->scoreFont()->name() == "Bravura" ? 0 : 0.5 * score()->spatium() * mag();
Expand Down Expand Up @@ -499,7 +498,7 @@ void BarLine::draw(QPainter* painter) const
QFont f("FreeSerif");
f.setPointSizeF(12 * spatium() * MScore::pixelRatio / SPATIUM20);
f.setBold(true);
QString str = m->len() > m->timesig() ? "+" : "-";
QString str = m->ticks() > m->timesig() ? "+" : "-";
QRectF r = QFontMetricsF(f, MScore::paintDevice()).boundingRect(str);
painter->setFont(f);
painter->drawText(-r.width(), 0.0, str);
Expand Down Expand Up @@ -1334,9 +1333,9 @@ QString BarLine::accessibleExtraInfo() const
}
}

int tick = seg->tick();
Fraction tick = seg->tick();

auto spanners = score()->spannerMap().findOverlapping(tick, tick);
auto spanners = score()->spannerMap().findOverlapping(tick.ticks(), tick.ticks());
for (auto interval : spanners) {
Spanner* s = interval.value;
if (!score()->selectionFilter().canSelect(s))
Expand Down
44 changes: 22 additions & 22 deletions libmscore/beam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ bool Beam::twoBeamedNotes()
if (c1->notes().size() != 1 || c2->notes().size() != 1)
return false;

int upDnLimit = staff()->lines(0) - 1; // was '4' hard-coded in the next 2 lines
int upDnLimit = staff()->lines(Fraction(0, 1)) - 1; // was '4' hard-coded in the next 2 lines
int dist1 = c1->upLine() - upDnLimit;
int dist2 = c2->upLine() - upDnLimit;
if ((dist1 == -dist2) || (-dist1 == dist2)) {
Expand Down Expand Up @@ -303,11 +303,11 @@ void Beam::layout1()
Chord* c2 = 0;

// TAB's with stem beside staves have special layout
if (staff()->isTabStaff(0) && !staff()->staffType(0)->stemThrough()) {
if (staff()->isTabStaff(Fraction(0,1)) && !staff()->staffType(Fraction(0,1))->stemThrough()) {
//TABULATURES: all beams (and related chords) are:
// UP or DOWN according to TAB duration position
// slope 0
_up = !staff()->staffType(0)->stemsDown();
_up = !staff()->staffType(Fraction(0,1))->stemsDown();
slope = 0.0;
_cross = false;
minMove = maxMove = 0; // no cross-beaming in TAB's!
Expand All @@ -322,7 +322,7 @@ void Beam::layout1()
}
}
}
else if (staff()->isDrumStaff(0)) {
else if (staff()->isDrumStaff(Fraction(0,1))) {
if (_direction != Direction::AUTO)
_up = _direction == Direction::UP;
else {
Expand All @@ -346,7 +346,7 @@ void Beam::layout1()

int mUp = 0;
int mDown = 0;
int upDnLimit = staff()->lines(0) - 1; // was '4' hard-coded in following code
int upDnLimit = staff()->lines(Fraction(0,1)) - 1; // was '4' hard-coded in following code

int staffIdx = -1;
for (ChordRest* cr : _elements) {
Expand Down Expand Up @@ -460,11 +460,11 @@ void Beam::layoutGraceNotes()
//
// determine beam stem direction
//
if (staff()->isTabStaff(0)) {
if (staff()->isTabStaff(Fraction(0,1))) {
//TABULATURES: all beams (and related chords) are:
// UP or DOWN according to TAB duration position
// slope 0
_up = !staff()->staffType(0)->stemsDown();
_up = !staff()->staffType(Fraction(0,1))->stemsDown();
}
else {
if (_direction != Direction::AUTO)
Expand Down Expand Up @@ -1099,7 +1099,7 @@ static int adjust(qreal _spatium4, int slant, const std::vector<ChordRest*>& cl)
// on tab staff, reduce a bit the stems (value 4 is experimental)
// TODO : proper fix should adapt all the numeric vaues used in Beam::computeStemLen() below
// to variable line distance
if (c1->staff() && c1->staff()->isTabStaff(0)) {
if (c1->staff() && c1->staff()->isTabStaff(Fraction(0,1))) {
ml = (ml != 0) ? ml - 4 : 0;
return ml;
}
Expand Down Expand Up @@ -1180,7 +1180,7 @@ void Beam::computeStemLen(const std::vector<ChordRest*>& cl, qreal& py1, int bea
qreal _spatium = spatium();
qreal _spatium4 = _spatium * .25;
// TAB: scale to staff line distance for vert. pos. within a staff
qreal _spStaff4 = staff()->isTabStaff(0) ? _spatium4 * staff()->lineDistance(0) : _spatium4;
qreal _spStaff4 = staff()->isTabStaff(Fraction(0,1)) ? _spatium4 * staff()->lineDistance(Fraction(0,1)) : _spatium4;
const ChordRest* c1 = cl.front();
const ChordRest* c2 = cl.back();
qreal dx = c2->pagePos().x() - c1->pagePos().x();
Expand Down Expand Up @@ -1524,8 +1524,8 @@ void Beam::layout2(std::vector<ChordRest*>crl, SpannerSegmentType, int frag)
size_t n = crl.size();

const StaffType* tab = 0;
if (staff()->isTabStaff(0) )
tab = staff()->staffType(0);
if (staff()->isTabStaff(Fraction(0,1)) )
tab = staff()->staffType(Fraction(0,1));
if (tab && !tab->stemThrough()) {
//
// TAB STAVES with stems beside staves: beam position is fixed depending on TAB parameters and chordrest up/down
Expand Down Expand Up @@ -1825,7 +1825,7 @@ void Beam::layout2(std::vector<ChordRest*>crl, SpannerSegmentType, int frag)
// unless this is start of sub-beam
const Groups& g = cr1->staff()->group(cr1->measure()->tick());
Fraction stretch = cr1->staff()->timeStretch(cr1->measure()->tick());
int currentTick = (cr1->rtick() * stretch.numerator()) / stretch.denominator();
int currentTick = (cr1->rtick() * stretch).ticks();
Beam::Mode bm = g.beamMode(currentTick, currentDuration.type());
int beamsIn;
if (bm == Beam::Mode::BEGIN32)
Expand All @@ -1836,7 +1836,7 @@ void Beam::layout2(std::vector<ChordRest*>crl, SpannerSegmentType, int frag)
beamsIn = prevCR->durationType().hooks();

// remember, we are checking whether nextCR would have started sub-beam *if* same duration as this
int nextTick = (nextCR->rtick() * stretch.numerator()) / stretch.denominator();
int nextTick = (nextCR->rtick() * stretch).ticks();
bm = g.beamMode(nextTick, currentDuration.type());

if (currentHooks - beamsOut > 1 && beamsIn > beamsOut && currentHooks > beamsIn) {
Expand All @@ -1854,29 +1854,29 @@ void Beam::layout2(std::vector<ChordRest*>crl, SpannerSegmentType, int frag)
else {
// determine if this is a logical group end as per 2) above

int baseTick = tuplet ? tuplet->tick() : cr1->measure()->tick();
int tickNext = nextCR->tick() - baseTick;
Fraction baseTick = tuplet ? tuplet->tick() : cr1->measure()->tick();;
Fraction tickNext = nextCR->tick() - baseTick;
if (tuplet) {
// for tuplets with odd ratios, apply ratio
// thus, we are performing calculation relative to apparent rather than actual beat
// for tuplets with even ratios, use actual beat
// see https://musescore.org/en/node/58061
Fraction r = tuplet->ratio();
if (r.numerator() & 1)
tickNext = (tickNext * r.numerator()) / r.denominator();
tickNext = tickNext * r;
}

// determine the tick length of a chord with one beam level less than this
// (i.e. twice the ticks of this)

int tickMod = cr1->duration().ticks() * 2; // (tickNext - (crl[c1]->tick() - baseTick)) * 2;
int tickMod = cr1->ticks().ticks() * 2; // (tickNext - (crl[c1]->tick() - baseTick)) * 2;

// if this completes, within the measure or tuplet, a unit of tickMod length, flip beam to left
// (allow some tolerance for tick rounding in tuplets
// without tuplet tolerance, could be simplified)

static const int BEAM_TUPLET_TOLERANCE = 6;
int mod = tickNext % tickMod;
int mod = tickNext.ticks() % tickMod;
if (mod <= BEAM_TUPLET_TOLERANCE || (tickMod - mod) <= BEAM_TUPLET_TOLERANCE)
len = -len;
}
Expand Down Expand Up @@ -2453,18 +2453,18 @@ void Beam::addSkyline(Skyline& sk)
// tick
//---------------------------------------------------------

int Beam::tick() const
Fraction Beam::tick() const
{
return _elements.empty() ? 0 : _elements.front()->tick();
return _elements.empty() ? Fraction(0, 1) : _elements.front()->segment()->tick();
}

//---------------------------------------------------------
// rtick
//---------------------------------------------------------

int Beam::rtick() const
Fraction Beam::rtick() const
{
return _elements.empty() ? 0 : _elements.front()->rtick();
return _elements.empty() ? Fraction(0, 1) : _elements.front()->segment()->rtick();
}
}

4 changes: 2 additions & 2 deletions libmscore/beam.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class Beam final : public Element {
virtual void editDrag(EditData&) override;
virtual void updateGrips(EditData&) const override;

virtual int tick() const override;
virtual int rtick() const override;
virtual Fraction tick() const override;
virtual Fraction rtick() const override;

virtual void write(XmlWriter& xml) const override;
virtual void read(XmlReader&) override;
Expand Down
Loading

0 comments on commit ec3be9a

Please sign in to comment.