Skip to content

Commit

Permalink
fix #87266: Metronome plays eighth notes if pickup measure has actual…
Browse files Browse the repository at this point in the history
… duration of 1/8
  • Loading branch information
lasconic committed Jun 23, 2016
1 parent 8e8c277 commit a005901
Showing 1 changed file with 29 additions and 18 deletions.
47 changes: 29 additions & 18 deletions libmscore/rendermidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,9 @@ int Score::renderMetronome(EventMap* events, Measure* m, int playPos, int tickOf
{
int msrTick = m->tick();
qreal tempo = tempomap()->tempo(msrTick);
const SigEvent sig = sigmap()->timesig(msrTick);
Fraction timeSig = sigmap()->timesig(msrTick).nominal();
int msrTicks = sig.timesig().ticks();
int numerator = timeSig.numerator();
int denominator = timeSig.denominator();
int clickTicks = MScore::division * 4 / denominator;
Expand All @@ -1540,33 +1542,42 @@ int Score::renderMetronome(EventMap* events, Measure* m, int playPos, int tickOf
// NUMBER OF TICKS
int numOfClicks = numerator; // default to a full measure of 'clicks'
int lastPause = clickTicks; // the number of ticks to wait after the last 'click'
// if not at the beginning of a measure, add clicks for the initial measure part
if (msrTick < playPos) {
int delta = playPos - msrTick;
int addClick = (delta + clickTicks - 1) / clickTicks; // round num. of clicks up
numOfClicks += addClick;
lastPause = delta - (addClick - 1) * clickTicks; // anything after last click time is final pause
int pickupClickOffset = 0;

if (countIn) {
// if not at the beginning of a measure, add clicks for the initial measure part
if (msrTick < playPos) {
int delta = playPos - msrTick;
int addClick = (delta + clickTicks - 1) / clickTicks; // round num. of clicks up
numOfClicks += addClick;
lastPause = delta - (addClick - 1) * clickTicks; // anything after last click time is final pause
}
// or if measure not complete (anacrusis), add clicks for the missing measure part
else if (m->ticks() < clickTicks * numerator) {
int delta = clickTicks * numerator - m->ticks();
int addClick = (delta + clickTicks - 1) / clickTicks;
numOfClicks += addClick;
lastPause = delta - (addClick - 1) * clickTicks;
}
}
// or if measure not complete (anacrusis), add clicks for the missing measure part
else if (m->ticks() < clickTicks * numerator) {
int delta = clickTicks * numerator - m->ticks();
int addClick = (delta + clickTicks - 1) / clickTicks;
numOfClicks += addClick;
lastPause = delta - (addClick - 1) * clickTicks;
else {
// compute pickup offset to avoid wrong tick sound
if (sig.nominal() != sig.timesig()) {
numOfClicks = msrTicks / clickTicks;
pickupClickOffset = numerator - numOfClicks;
}
}
/*
// MIN_CLICKS: be sure to have at least MIN_CLICKS clicks: if less, add full measures
while (numOfClicks < MIN_CLICKS)
numOfClicks += numerator;
*/

// click-clack-clack triplets
if (triplets)
numerator = 3;
int tick = 0;
NPlayEvent event;
for (int i = 0; i < numOfClicks; i++) {
tick = (countIn ? 0 : m->tick()) + i * clickTicks + tickOffset;
event.setType((i % numerator) == 0 ? ME_TICK1 : ME_TICK2);
// do not add a tick if the clickticks is greater than the measure duration
// except in countIn
event.setType(((i + pickupClickOffset) % numerator) == 0 ? ME_TICK1 : ME_TICK2);
events->insert(std::pair<int,NPlayEvent>(tick, event));
}
return tick + lastPause;
Expand Down

0 comments on commit a005901

Please sign in to comment.