Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "sig.h"
24 :
25 : #include "log.h"
26 :
27 : using namespace mu;
28 :
29 : namespace mu::engraving {
30 : //---------------------------------------------------------
31 : // ticks_beat
32 : //---------------------------------------------------------
33 :
34 6505 : int ticks_beat(int n)
35 : {
36 6505 : int m = (Constants::DIVISION * 4) / n;
37 6505 : if ((Constants::DIVISION* 4) % n) {
38 0 : ASSERT_X(String(u"Mscore: ticks_beat(): bad divisor %1").arg(n));
39 : }
40 6505 : return m;
41 : }
42 :
43 : //---------------------------------------------------------
44 : // ticks_measure
45 : //---------------------------------------------------------
46 :
47 11995 : static int ticks_measure(const Fraction& f)
48 : {
49 11995 : return (Constants::DIVISION * 4 * f.numerator()) / f.denominator();
50 : }
51 :
52 : //---------------------------------------------------------
53 : // rtick2beatType
54 : // caller must adjust rtick as appropriate if the measure's
55 : // actual timeSig is different from the nominal timeSig.
56 : //---------------------------------------------------------
57 :
58 4760 : BeatType TimeSigFrac::rtick2beatType(int rtick) const
59 : {
60 4760 : if (rtick == 0) {
61 379 : return BeatType::DOWNBEAT; // note: only return DOWNBEAT for rtick = 0, not for rtick = measureTicks,
62 : }
63 4381 : if (rtick % dUnitTicks() != 0) {
64 605 : return BeatType::SUBBEAT;
65 : }
66 :
67 3776 : if (isCompound()) {
68 1115 : if (rtick % beatTicks() != 0) {
69 645 : return BeatType::COMPOUND_SUBBEAT;
70 : }
71 : }
72 :
73 3131 : const int beatNum = rtick / beatTicks();
74 :
75 3131 : int stressBeat = 0;
76 :
77 3131 : if (isTriple()) {
78 256 : stressBeat = 3;
79 2875 : } else if (isDuple()) {
80 2631 : stressBeat = 2;
81 : } else {
82 244 : stressBeat = (numerator() + 1) / 2; // Assumes 5/4 timeSig = (3+2)/4. (The same assumption is used for beaming)
83 : }
84 3131 : if (stressBeat && beatNum % stressBeat == 0) {
85 1414 : return isCompound() ? BeatType::COMPOUND_STRESSED : BeatType::SIMPLE_STRESSED;
86 : }
87 :
88 1717 : return isCompound() ? BeatType::COMPOUND_UNSTRESSED : BeatType::SIMPLE_UNSTRESSED;
89 : }
90 :
91 : //---------------------------------------------------------
92 : // strongestBeatInRange
93 : // dUnitsCrossed - pointer to store number crossed
94 : // subbeatTick - pointer to store tick of strongest beat
95 : // saveLast - which tick to store if strongest type is
96 : // crossed more than once
97 : //
98 : // caller must adjust rticks as appropriate if the measure's
99 : // actual timeSig is different from the nominal timeSig.
100 : //---------------------------------------------------------
101 :
102 1042 : BeatType TimeSigFrac::strongestBeatInRange(int rtick1, int rtick2, int* dUnitsCrossed, int* subbeatTick, bool saveLast) const
103 : {
104 1042 : assert(rtick2 > rtick1);
105 :
106 1042 : BeatType strongest = BeatType::SUBBEAT;
107 :
108 2585 : for (int rtick = rtick1 + ticksToNextDUnit(rtick1); rtick < rtick2; rtick += dUnitTicks()) {
109 1543 : if (dUnitsCrossed) {
110 1543 : (*dUnitsCrossed)++;
111 : }
112 1543 : BeatType type = rtick2beatType(rtick);
113 1543 : if (static_cast<int>(type) < static_cast<int>(strongest) + saveLast) { // "<" behaves like "<=" if saveLast is true
114 1274 : strongest = type;
115 1274 : if (subbeatTick) {
116 1274 : (*subbeatTick) = rtick;
117 : }
118 : }
119 : }
120 :
121 1042 : return strongest;
122 : }
123 :
124 : //---------------------------------------------------------
125 : // subbeatTicks
126 : // divides dUnitTicks() by 2 once for each level.
127 : //---------------------------------------------------------
128 :
129 192 : int TimeSigFrac::subbeatTicks(int level) const
130 : {
131 192 : assert(level <= maxSubbeatLevel());
132 192 : int subbeatTicks = dUnitTicks();
133 402 : while (level > 0) {
134 210 : subbeatTicks /= 2;
135 210 : level--;
136 : }
137 192 : return subbeatTicks;
138 : }
139 :
140 : //---------------------------------------------------------
141 : // maxSubbeatLevel
142 : // subdivision beyond this level would result in rounding errors
143 : //---------------------------------------------------------
144 :
145 192 : int TimeSigFrac::maxSubbeatLevel() const
146 : {
147 192 : int level = 0;
148 192 : int subbeatTicks = dUnitTicks();
149 1152 : while (subbeatTicks % 2 == 0) {
150 960 : subbeatTicks /= 2;
151 960 : level++;
152 : }
153 192 : return level;
154 : }
155 :
156 : //---------------------------------------------------------
157 : // rtick2subbeatLevel
158 : // returns 0 if rtick is on a beat or denominator unit.
159 : // returns 1 if rtick lies halfway between dUnits
160 : // returns 2 if rtick lies on a multiple of 1/4 of dUnit
161 : // 3 1/8
162 : // 4 1/16
163 : // n 1/(2**n)
164 : // returns -(n+1) if max n is reached and rtick still not found.
165 : //
166 : // Caller must adjust rtick as appropriate if the measure's
167 : // actual timeSig is different from the nominal timeSig.
168 : //---------------------------------------------------------
169 :
170 5066 : int TimeSigFrac::rtick2subbeatLevel(int rtick) const
171 : {
172 5066 : int level = 0;
173 5066 : int subbeatTicks = dUnitTicks();
174 5066 : int remainder = rtick % subbeatTicks;
175 7429 : while (remainder != 0) {
176 2366 : level++;
177 2366 : if (subbeatTicks % 2 != 0) {
178 3 : return -level; // further sub-division would split measure into chunks of unequal length.
179 : }
180 2363 : subbeatTicks /= 2;
181 2363 : remainder %= subbeatTicks;
182 : }
183 5063 : return level;
184 : }
185 :
186 : //---------------------------------------------------------
187 : // strongestSubbeatLevelInRange
188 : // Return value is negative if none are found.
189 : //
190 : // Caller must adjust rtick as appropriate if the measure's
191 : // actual timeSig is different from the nominal timeSig.
192 : //---------------------------------------------------------
193 :
194 2533 : int TimeSigFrac::strongestSubbeatLevelInRange(int rtick1, int rtick2, int* subbeatTick) const
195 : {
196 2533 : assert(rtick2 > rtick1);
197 :
198 2533 : for (int level = 0, subbeatTicks = dUnitTicks();;) {
199 5045 : int n = rtick1 / subbeatTicks;
200 5045 : int m = (rtick2 - 1) / subbeatTicks; // -1 to make the range exclusive
201 5045 : if (m > n) {
202 2522 : if (subbeatTick) {
203 2522 : (*subbeatTick) = m * subbeatTicks;
204 : }
205 2522 : return level;
206 : }
207 2523 : level++;
208 2523 : if (subbeatTicks % 2 != 0) {
209 11 : return -level; // further sub-division would split measure into chunks of unequal length.
210 : }
211 2512 : subbeatTicks /= 2;
212 2512 : }
213 : }
214 :
215 : //---------------------------------------------------------
216 : // operator==
217 : //---------------------------------------------------------
218 :
219 27 : bool SigEvent::operator==(const SigEvent& e) const
220 : {
221 27 : return m_timesig.identical(e.m_timesig);
222 : }
223 :
224 : //---------------------------------------------------------
225 : // add
226 : //---------------------------------------------------------
227 :
228 : const TimeSigFrac TimeSigMap::DEFAULT_TIME_SIGNATURE(4, 4);
229 :
230 2904 : void TimeSigMap::add(int tick, const Fraction& f)
231 : {
232 2904 : if (!f.isValid()) {
233 0 : LOGD("illegal signature %d/%d", f.numerator(), f.denominator());
234 : }
235 2904 : (*this)[tick] = SigEvent(f);
236 2904 : normalize();
237 2904 : }
238 :
239 2693 : void TimeSigMap::add(int tick, const SigEvent& ev)
240 : {
241 2693 : (*this)[tick] = ev;
242 2693 : normalize();
243 2693 : }
244 :
245 : //---------------------------------------------------------
246 : // del
247 : //---------------------------------------------------------
248 :
249 0 : void TimeSigMap::del(int tick)
250 : {
251 0 : erase(tick);
252 0 : normalize();
253 0 : }
254 :
255 : //---------------------------------------------------------
256 : // clearRange
257 : // Clears the given range, start tick included, end tick
258 : // excluded.
259 : //---------------------------------------------------------
260 :
261 0 : void TimeSigMap::clearRange(int tick1, int tick2)
262 : {
263 0 : iterator first = lower_bound(tick1);
264 0 : iterator last = lower_bound(tick2);
265 0 : if (first == last) {
266 0 : return;
267 : }
268 0 : erase(first, last);
269 0 : normalize();
270 : }
271 :
272 : //---------------------------------------------------------
273 : // TimeSigMap::normalize
274 : //---------------------------------------------------------
275 :
276 5623 : void TimeSigMap::normalize()
277 : {
278 5623 : int z = 4;
279 5623 : int n = 4;
280 5623 : int tick = 0;
281 5623 : TimeSigFrac bar;
282 5623 : int tm = ticks_measure(TimeSigFrac(z, n));
283 :
284 11995 : for (auto i = begin(); i != end(); ++i) {
285 6372 : SigEvent& e = i->second;
286 6372 : bar += TimeSigFrac(i->first - tick, tm).reduced();
287 6372 : e.setBar(bar.numerator() / bar.denominator());
288 6372 : tick = i->first;
289 6372 : tm = ticks_measure(e.timesig());
290 : }
291 5623 : }
292 :
293 : //---------------------------------------------------------
294 : // timesig
295 : //---------------------------------------------------------
296 :
297 6443 : const SigEvent& TimeSigMap::timesig(int tick) const
298 : {
299 6443 : static const SigEvent ev(DEFAULT_TIME_SIGNATURE);
300 6443 : if (empty()) {
301 86 : return ev;
302 : }
303 6357 : auto i = upper_bound(tick);
304 6357 : if (i != begin()) {
305 6357 : --i;
306 : }
307 6357 : return i->second;
308 : }
309 :
310 : //---------------------------------------------------------
311 : // tickValues
312 : // t - some time moment on timeline (in ticks)
313 : //
314 : // Result - values computed for this time moment:
315 : // bar - index of bar containing time moment t
316 : // beat - index of beat in bar containing t
317 : // tick - position of t in beat (in ticks)
318 : //---------------------------------------------------------
319 :
320 1827 : void TimeSigMap::tickValues(int t, int* bar, int* beat, int* tick) const
321 : {
322 1827 : if (empty()) {
323 0 : *bar = 0;
324 0 : *beat = 0;
325 0 : *tick = 0;
326 0 : return;
327 : }
328 1827 : auto e = upper_bound(t);
329 1827 : IF_ASSERT_FAILED_X(e != begin(), String(u"tickValue(0x%1) not found").arg(t)) {
330 0 : *bar = 0;
331 0 : *beat = 0;
332 0 : *tick = 0;
333 0 : return;
334 : }
335 1827 : --e;
336 1827 : int delta = t - e->first;
337 1827 : int ticksB = ticks_beat(e->second.timesig().denominator()); // ticks in beat
338 1827 : int ticksM = ticksB * e->second.timesig().numerator(); // ticks in measure (bar)
339 1827 : if (ticksM == 0) {
340 0 : LOGD("TimeSigMap::tickValues: at %d %s", t, muPrintable(e->second.timesig().toString()));
341 0 : *bar = 0;
342 0 : *beat = 0;
343 0 : *tick = 0;
344 0 : return;
345 : }
346 1827 : *bar = e->second.bar() + delta / ticksM;
347 1827 : int rest = delta % ticksM;
348 1827 : *beat = rest / ticksB;
349 1827 : *tick = rest % ticksB;
350 : }
351 :
352 : //---------------------------------------------------------
353 : // pos
354 : // Return string representation of tick position.
355 : // This is not reentrant and only for debugging!
356 : //---------------------------------------------------------
357 :
358 0 : String TimeSigMap::pos(int t) const
359 : {
360 : int bar, beat, tick;
361 0 : tickValues(t, &bar, &beat, &tick);
362 0 : return String(u"%1:%2:%3").arg(bar + 1, beat, tick);
363 : }
364 :
365 : //---------------------------------------------------------
366 : // bar2tick
367 : // Returns the absolute start time (in ticks)
368 : // of beat in bar
369 : //---------------------------------------------------------
370 :
371 4603 : int TimeSigMap::bar2tick(int bar, int beat) const
372 : {
373 : // bar - index of current bar (terminology: bar == measure)
374 : // beat - index of beat in current bar
375 4603 : auto e = begin();
376 :
377 9382 : for (; e != end(); ++e) {
378 4858 : if (bar < e->second.bar()) {
379 79 : break;
380 : }
381 : }
382 4603 : if (empty() || e == begin()) {
383 0 : LOGD("TimeSigMap::bar2tick(): not found(%d,%d) not found", bar, beat);
384 0 : if (empty()) {
385 0 : LOGD(" list is empty");
386 : }
387 0 : return 0;
388 : }
389 4603 : --e; // current TimeSigMap value
390 4603 : int ticksB = ticks_beat(e->second.timesig().denominator()); // ticks per beat
391 4603 : int ticksM = ticksB * e->second.timesig().numerator(); // bar length in ticks
392 4603 : return e->first + (bar - e->second.bar()) * ticksM + ticksB * beat;
393 : }
394 :
395 : //---------------------------------------------------------
396 : // ticksPerMeasure
397 : //---------------------------------------------------------
398 :
399 0 : int ticksPerMeasure(int numerator, int denominator)
400 : {
401 0 : return ticks_beat(denominator) * numerator;
402 : }
403 :
404 : //---------------------------------------------------------
405 : // rasterEval
406 : //---------------------------------------------------------
407 :
408 0 : unsigned rasterEval(unsigned t, int raster, int startTick,
409 : int numerator, int denominator, int addition)
410 : {
411 0 : int delta = t - startTick;
412 0 : int ticksM = ticksPerMeasure(numerator, denominator);
413 0 : if (raster == 0) {
414 0 : raster = ticksM;
415 : }
416 0 : int rest = delta % ticksM;
417 0 : int bb = (delta / ticksM) * ticksM;
418 0 : return startTick + bb + ((rest + addition) / raster) * raster;
419 : }
420 :
421 : //---------------------------------------------------------
422 : // raster
423 : //---------------------------------------------------------
424 :
425 0 : unsigned TimeSigMap::raster(unsigned t, int raster) const
426 : {
427 0 : if (raster == 1) {
428 0 : return t;
429 : }
430 0 : auto e = upper_bound(t);
431 0 : if (e == end()) {
432 0 : LOGD("TimeSigMap::raster(%x,)", t);
433 0 : return t;
434 : }
435 0 : auto timesig = e->second.timesig();
436 0 : return rasterEval(t, raster, e->first, timesig.numerator(),
437 0 : timesig.denominator(), raster / 2);
438 : }
439 :
440 : //---------------------------------------------------------
441 : // raster1
442 : // round down
443 : //---------------------------------------------------------
444 :
445 0 : unsigned TimeSigMap::raster1(unsigned t, int raster) const
446 : {
447 0 : if (raster == 1) {
448 0 : return t;
449 : }
450 0 : auto e = upper_bound(t);
451 0 : auto timesig = e->second.timesig();
452 0 : return rasterEval(t, raster, e->first, timesig.numerator(),
453 0 : timesig.denominator(), 0);
454 : }
455 :
456 : //---------------------------------------------------------
457 : // raster2
458 : // round up
459 : //---------------------------------------------------------
460 :
461 0 : unsigned TimeSigMap::raster2(unsigned t, int raster) const
462 : {
463 0 : if (raster == 1) {
464 0 : return t;
465 : }
466 0 : auto e = upper_bound(t);
467 0 : auto timesig = e->second.timesig();
468 0 : return rasterEval(t, raster, e->first, timesig.numerator(),
469 0 : timesig.denominator(), raster - 1);
470 : }
471 :
472 : //---------------------------------------------------------
473 : // rasterStep
474 : //---------------------------------------------------------
475 :
476 0 : int TimeSigMap::rasterStep(unsigned t, int raster) const
477 : {
478 0 : if (raster == 0) {
479 0 : auto timesig = upper_bound(t)->second.timesig();
480 0 : return ticksPerMeasure(timesig.denominator(), timesig.numerator());
481 : }
482 0 : return raster;
483 : }
484 :
485 : //---------------------------------------------------------
486 : // TimeSigMap::dump
487 : //---------------------------------------------------------
488 :
489 0 : void TimeSigMap::dump() const
490 : {
491 0 : LOGD("TimeSigMap:");
492 0 : for (auto i = begin(); i != end(); ++i) {
493 0 : LOGD("%6d timesig: %s measure: %d",
494 0 : i->first, muPrintable(i->second.timesig().toString()), i->second.bar());
495 : }
496 0 : }
497 :
498 : //---------------------------------------------------------
499 : // dUnitTicks
500 : //---------------------------------------------------------
501 :
502 20714 : int TimeSigFrac::dUnitTicks() const
503 : {
504 20714 : return (4 * Constants::DIVISION) / denominator();
505 : }
506 : }
|