1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2002-2007 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12
13 #include "sig.h"
14 #include "xml.h"
15
16 namespace Ms {
17
18 //---------------------------------------------------------
19 // ticks_beat
20 //---------------------------------------------------------
21
ticks_beat(int n)22 int ticks_beat(int n)
23 {
24 int m = (MScore::division * 4) / n;
25 if ((MScore::division * 4) % n) {
26 qFatal("Mscore: ticks_beat(): bad divisor %d", n);
27 }
28 return m;
29 }
30
31 //---------------------------------------------------------
32 // ticks_measure
33 //---------------------------------------------------------
34
ticks_measure(const Fraction & f)35 static int ticks_measure(const Fraction& f)
36 {
37 return (MScore::division * 4 * f.numerator()) / f.denominator();
38 }
39
40 //---------------------------------------------------------
41 // rtick2beatType
42 // caller must adjust rtick as appropriate if the measure's
43 // actual timeSig is different from the nominal timeSig.
44 //---------------------------------------------------------
45
rtick2beatType(int rtick) const46 BeatType TimeSigFrac::rtick2beatType(int rtick) const
47 {
48 if (rtick == 0)
49 return BeatType::DOWNBEAT; // note: only return DOWNBEAT for rtick = 0, not for rtick = measureTicks,
50
51 if (rtick % dUnitTicks() != 0)
52 return BeatType::SUBBEAT;
53
54 if (isCompound()) {
55 if (rtick % beatTicks() != 0)
56 return BeatType::COMPOUND_SUBBEAT;
57 }
58
59 const int beatNum = rtick / beatTicks();
60
61 int stressBeat = 0;
62
63 if (isTriple())
64 stressBeat = 3;
65 else if (isDuple())
66 stressBeat = 2;
67 else
68 stressBeat = (numerator() + 1) / 2; // Assumes 5/4 timeSig = (3+2)/4. (The same assumption is used for beaming)
69
70 if (stressBeat && beatNum % stressBeat == 0)
71 return isCompound() ? BeatType::COMPOUND_STRESSED : BeatType::SIMPLE_STRESSED;
72
73 return isCompound() ? BeatType::COMPOUND_UNSTRESSED : BeatType::SIMPLE_UNSTRESSED;
74 }
75
76 //---------------------------------------------------------
77 // strongestBeatInRange
78 // dUnitsCrossed - pointer to store number crossed
79 // subbeatTick - pointer to store tick of strongest beat
80 // saveLast - which tick to store if strongest type is
81 // crossed more than once
82 //
83 // caller must adjust rticks as appropriate if the measure's
84 // actual timeSig is different from the nominal timeSig.
85 //---------------------------------------------------------
86
strongestBeatInRange(int rtick1,int rtick2,int * dUnitsCrossed,int * subbeatTick,bool saveLast) const87 BeatType TimeSigFrac::strongestBeatInRange(int rtick1, int rtick2, int* dUnitsCrossed, int* subbeatTick, bool saveLast) const
88 {
89 Q_ASSERT(rtick2 > rtick1);
90
91 BeatType strongest = BeatType::SUBBEAT;
92
93 for (int rtick = rtick1 + ticksToNextDUnit(rtick1); rtick < rtick2; rtick += dUnitTicks()) {
94 if (dUnitsCrossed)
95 (*dUnitsCrossed)++;
96 BeatType type = rtick2beatType(rtick);
97 if (static_cast<int>(type) < static_cast<int>(strongest) + saveLast) { // "<" behaves like "<=" if saveLast is true
98 strongest = type;
99 if (subbeatTick)
100 (*subbeatTick) = rtick;
101 }
102 }
103
104 return strongest;
105 }
106
107 //---------------------------------------------------------
108 // subbeatTicks
109 // divides dUnitTicks() by 2 once for each level.
110 //---------------------------------------------------------
111
subbeatTicks(int level) const112 int TimeSigFrac::subbeatTicks(int level) const
113 {
114 Q_ASSERT(level <= maxSubbeatLevel());
115 int subbeatTicks = dUnitTicks();
116 while (level > 0) {
117 subbeatTicks /= 2;
118 level--;
119 }
120 return subbeatTicks;
121 }
122
123 //---------------------------------------------------------
124 // maxSubbeatLevel
125 // subdivision beyond this level would result in rounding errors
126 //---------------------------------------------------------
127
maxSubbeatLevel() const128 int TimeSigFrac::maxSubbeatLevel() const
129 {
130 int level = 0;
131 int subbeatTicks = dUnitTicks();
132 while (subbeatTicks % 2 == 0) {
133 subbeatTicks /= 2;
134 level++;
135 }
136 return level;
137 }
138
139 //---------------------------------------------------------
140 // rtick2subbeatLevel
141 // returns 0 if rtick is on a beat or denominator unit.
142 // returns 1 if rtick lies halfway between dUnits
143 // returns 2 if rtick lies on a multiple of 1/4 of dUnit
144 // 3 1/8
145 // 4 1/16
146 // n 1/(2**n)
147 // returns -(n+1) if max n is reached and rtick still not found.
148 //
149 // Caller must adjust rtick as appropriate if the measure's
150 // actual timeSig is different from the nominal timeSig.
151 //---------------------------------------------------------
152
rtick2subbeatLevel(int rtick) const153 int TimeSigFrac::rtick2subbeatLevel(int rtick) const
154 {
155 int level = 0;
156 int subbeatTicks = dUnitTicks();
157 int remainder = rtick % subbeatTicks;
158 while (remainder != 0) {
159 level++;
160 if (subbeatTicks % 2 != 0)
161 return -level; // further sub-division would split measure into chunks of unequal length.
162 subbeatTicks /= 2;
163 remainder %= subbeatTicks;
164 }
165 return level;
166 }
167
168 //---------------------------------------------------------
169 // strongestSubbeatLevelInRange
170 // Return value is negative if none are found.
171 //
172 // Caller must adjust rtick as appropriate if the measure's
173 // actual timeSig is different from the nominal timeSig.
174 //---------------------------------------------------------
175
strongestSubbeatLevelInRange(int rtick1,int rtick2,int * subbeatTick) const176 int TimeSigFrac::strongestSubbeatLevelInRange(int rtick1, int rtick2, int* subbeatTick) const
177 {
178 Q_ASSERT(rtick2 > rtick1);
179
180 for (int level = 0, subbeatTicks = dUnitTicks();;) {
181 int n = rtick1 / subbeatTicks;
182 int m = (rtick2 - 1) / subbeatTicks; // -1 to make the range exclusive
183 if (m > n) {
184 if (subbeatTick)
185 (*subbeatTick) = m * subbeatTicks;
186 return level;
187 }
188 level++;
189 if (subbeatTicks % 2 != 0)
190 return -level; // further sub-division would split measure into chunks of unequal length.
191 subbeatTicks /= 2;
192 }
193 }
194
195 //---------------------------------------------------------
196 // operator==
197 //---------------------------------------------------------
198
operator ==(const SigEvent & e) const199 bool SigEvent::operator==(const SigEvent& e) const
200 {
201 return (_timesig.identical(e._timesig));
202 }
203
204 //---------------------------------------------------------
205 // add
206 //---------------------------------------------------------
207
add(int tick,const Fraction & f)208 void TimeSigMap::add(int tick, const Fraction& f)
209 {
210 if (!f.isValid()) {
211 qDebug("illegal signature %d/%d", f.numerator(), f.denominator());
212 }
213 (*this)[tick] = SigEvent(f);
214 normalize();
215 }
216
add(int tick,const SigEvent & ev)217 void TimeSigMap::add(int tick, const SigEvent& ev)
218 {
219 (*this)[tick] = ev;
220 normalize();
221 }
222
223 //---------------------------------------------------------
224 // del
225 //---------------------------------------------------------
226
del(int tick)227 void TimeSigMap::del(int tick)
228 {
229 erase(tick);
230 normalize();
231 }
232
233 //---------------------------------------------------------
234 // clearRange
235 // Clears the given range, start tick included, end tick
236 // excluded.
237 //---------------------------------------------------------
238
clearRange(int tick1,int tick2)239 void TimeSigMap::clearRange(int tick1, int tick2)
240 {
241 iterator first = lower_bound(tick1);
242 iterator last = lower_bound(tick2);
243 if (first == last)
244 return;
245 erase(first, last);
246 normalize();
247 }
248
249 //---------------------------------------------------------
250 // TimeSigMap::normalize
251 //---------------------------------------------------------
252
normalize()253 void TimeSigMap::normalize()
254 {
255 int z = 4;
256 int n = 4;
257 int tick = 0;
258 TimeSigFrac bar;
259 int tm = ticks_measure(TimeSigFrac(z, n));
260
261 for (auto i = begin(); i != end(); ++i) {
262 SigEvent& e = i->second;
263 bar += TimeSigFrac(i->first - tick, tm).reduced();
264 e.setBar(bar.numerator() / bar.denominator());
265 tick = i->first;
266 tm = ticks_measure(e.timesig());
267 }
268 }
269
270 //---------------------------------------------------------
271 // timesig
272 //---------------------------------------------------------
273
timesig(int tick) const274 const SigEvent& TimeSigMap::timesig(int tick) const
275 {
276 static const SigEvent ev(TimeSigFrac(4, 4));
277 if (empty())
278 return ev;
279 auto i = upper_bound(tick);
280 if (i != begin())
281 --i;
282 return i->second;
283 }
284
285 //---------------------------------------------------------
286 // tickValues
287 // t - some time moment on timeline (in ticks)
288 //
289 // Result - values computed for this time moment:
290 // bar - index of bar containing time moment t
291 // beat - index of beat in bar containing t
292 // tick - position of t in beat (in ticks)
293 //---------------------------------------------------------
294
tickValues(int t,int * bar,int * beat,int * tick) const295 void TimeSigMap::tickValues(int t, int* bar, int* beat, int* tick) const
296 {
297 if (empty()) {
298 *bar = 0;
299 *beat = 0;
300 *tick = 0;
301 return;
302 }
303 auto e = upper_bound(t);
304 if (empty() || e == begin()) {
305 qFatal("tickValue(0x%x) not found", t);
306 }
307 --e;
308 int delta = t - e->first;
309 int ticksB = ticks_beat(e->second.timesig().denominator()); // ticks in beat
310 int ticksM = ticksB * e->second.timesig().numerator(); // ticks in measure (bar)
311 if (ticksM == 0) {
312 qDebug("TimeSigMap::tickValues: at %d %s", t, qPrintable(e->second.timesig().print()));
313 *bar = 0;
314 *beat = 0;
315 *tick = 0;
316 return;
317 }
318 *bar = e->second.bar() + delta / ticksM;
319 int rest = delta % ticksM;
320 *beat = rest / ticksB;
321 *tick = rest % ticksB;
322 }
323
324 //---------------------------------------------------------
325 // pos
326 // Return string representation of tick position.
327 // This is not reentrant and only for debugging!
328 //---------------------------------------------------------
329
pos(int t) const330 QString TimeSigMap::pos(int t) const
331 {
332 int bar, beat, tick;
333 tickValues(t, &bar, &beat, &tick);
334 return QString("%1:%2:%3").arg(bar+1).arg(beat).arg(tick);
335 }
336
337 //---------------------------------------------------------
338 // bar2tick
339 // Returns the absolute start time (in ticks)
340 // of beat in bar
341 //---------------------------------------------------------
342
bar2tick(int bar,int beat) const343 int TimeSigMap::bar2tick(int bar, int beat) const
344 {
345 // bar - index of current bar (terminology: bar == measure)
346 // beat - index of beat in current bar
347 auto e = begin();
348
349 for (; e != end(); ++e) {
350 if (bar < e->second.bar())
351 break;
352 }
353 if (empty() || e == begin()) {
354 qDebug("TimeSigMap::bar2tick(): not found(%d,%d) not found", bar, beat);
355 if (empty())
356 qDebug(" list is empty");
357 return 0;
358 }
359 --e; // current TimeSigMap value
360 int ticksB = ticks_beat(e->second.timesig().denominator()); // ticks per beat
361 int ticksM = ticksB * e->second.timesig().numerator(); // bar length in ticks
362 return e->first + (bar - e->second.bar()) * ticksM + ticksB * beat;
363 }
364
365 //---------------------------------------------------------
366 // TimeSigMap::write
367 //---------------------------------------------------------
368
write(XmlWriter & xml) const369 void TimeSigMap::write(XmlWriter& xml) const
370 {
371 xml.stag("siglist");
372 for (auto i = begin(); i != end(); ++i)
373 i->second.write(xml, i->first);
374 xml.etag();
375 }
376
377 //---------------------------------------------------------
378 // TimeSigMap::read
379 //---------------------------------------------------------
380
read(XmlReader & e,int fileDivision)381 void TimeSigMap::read(XmlReader& e, int fileDivision)
382 {
383 while (e.readNextStartElement()) {
384 const QStringRef& tag(e.name());
385 if (tag == "sig") {
386 SigEvent t;
387 int tick = t.read(e, fileDivision);
388 (*this)[tick] = t;
389 }
390 else
391 e.unknown();
392 }
393 normalize();
394 }
395
396 //---------------------------------------------------------
397 // SigEvent
398 //---------------------------------------------------------
399
SigEvent(const SigEvent & e)400 SigEvent::SigEvent(const SigEvent& e)
401 {
402 _timesig = e._timesig;
403 _nominal = e._nominal;
404 _bar = e._bar;
405 }
406
407 //---------------------------------------------------------
408 // SigEvent::write
409 //---------------------------------------------------------
410
write(XmlWriter & xml,int tick) const411 void SigEvent::write(XmlWriter& xml, int tick) const
412 {
413 xml.stag(QString("sig tick=\"%1\"").arg(tick));
414 xml.tag("nom", _timesig.numerator());
415 xml.tag("denom", _timesig.denominator());
416 xml.etag();
417 }
418
419 //---------------------------------------------------------
420 // SigEvent::read
421 //---------------------------------------------------------
422
read(XmlReader & e,int fileDivision)423 int SigEvent::read(XmlReader& e, int fileDivision)
424 {
425 int tick = e.intAttribute("tick", 0);
426 tick = tick * MScore::division / fileDivision;
427
428 int numerator = 1;
429 int denominator = 1;
430 int denominator2 = -1;
431 int numerator2 = -1;
432
433 while (e.readNextStartElement()) {
434 const QStringRef& tag(e.name());
435 if (tag == "nom")
436 numerator = e.readInt();
437 else if (tag == "denom")
438 denominator = e.readInt();
439 else if (tag == "nom2")
440 numerator2 = e.readInt();
441 else if (tag == "denom2")
442 denominator2 = e.readInt();
443 else
444 e.unknown();
445 }
446 if ((numerator2 == -1) || (denominator2 == -1)) {
447 numerator2 = numerator;
448 denominator2 = denominator;
449 }
450 _timesig = TimeSigFrac(numerator, denominator);
451 _nominal = TimeSigFrac(numerator2, denominator2);
452 return tick;
453 }
454
455 //---------------------------------------------------------
456 // ticksPerMeasure
457 //---------------------------------------------------------
458
ticksPerMeasure(int numerator,int denominator)459 int ticksPerMeasure(int numerator, int denominator)
460 {
461 return ticks_beat(denominator) * numerator;
462 }
463
464 //---------------------------------------------------------
465 // rasterEval
466 //---------------------------------------------------------
467
rasterEval(unsigned t,int raster,int startTick,int numerator,int denominator,int addition)468 unsigned rasterEval(unsigned t, int raster, int startTick,
469 int numerator, int denominator, int addition)
470 {
471 int delta = t - startTick;
472 int ticksM = ticksPerMeasure(numerator, denominator);
473 if (raster == 0)
474 raster = ticksM;
475 int rest = delta % ticksM;
476 int bb = (delta / ticksM) * ticksM;
477 return startTick + bb + ((rest + addition) / raster) * raster;
478 }
479
480 //---------------------------------------------------------
481 // raster
482 //---------------------------------------------------------
483
raster(unsigned t,int raster) const484 unsigned TimeSigMap::raster(unsigned t, int raster) const
485 {
486 if (raster == 1)
487 return t;
488 auto e = upper_bound(t);
489 if (e == end()) {
490 qDebug("TimeSigMap::raster(%x,)", t);
491 return t;
492 }
493 auto timesig = e->second.timesig();
494 return rasterEval(t, raster, e->first, timesig.numerator(),
495 timesig.denominator(), raster / 2);
496 }
497
498 //---------------------------------------------------------
499 // raster1
500 // round down
501 //---------------------------------------------------------
502
raster1(unsigned t,int raster) const503 unsigned TimeSigMap::raster1(unsigned t, int raster) const
504 {
505 if (raster == 1)
506 return t;
507 auto e = upper_bound(t);
508 auto timesig = e->second.timesig();
509 return rasterEval(t, raster, e->first, timesig.numerator(),
510 timesig.denominator(), 0);
511 }
512
513 //---------------------------------------------------------
514 // raster2
515 // round up
516 //---------------------------------------------------------
517
raster2(unsigned t,int raster) const518 unsigned TimeSigMap::raster2(unsigned t, int raster) const
519 {
520 if (raster == 1)
521 return t;
522 auto e = upper_bound(t);
523 auto timesig = e->second.timesig();
524 return rasterEval(t, raster, e->first, timesig.numerator(),
525 timesig.denominator(), raster - 1);
526 }
527
528 //---------------------------------------------------------
529 // rasterStep
530 //---------------------------------------------------------
531
rasterStep(unsigned t,int raster) const532 int TimeSigMap::rasterStep(unsigned t, int raster) const
533 {
534 if (raster == 0) {
535 auto timesig = upper_bound(t)->second.timesig();
536 return ticksPerMeasure(timesig.denominator(), timesig.numerator());
537 }
538 return raster;
539 }
540
541 //---------------------------------------------------------
542 // TimeSigMap::dump
543 //---------------------------------------------------------
544
dump() const545 void TimeSigMap::dump() const
546 {
547 qDebug("TimeSigMap:");
548 for (auto i = begin(); i != end(); ++i)
549 qDebug("%6d timesig: %s measure: %d",
550 i->first, qPrintable(i->second.timesig().print()), i->second.bar());
551 }
552
553 //---------------------------------------------------------
554 // dUnitTicks
555 //---------------------------------------------------------
556
dUnitTicks() const557 int TimeSigFrac::dUnitTicks() const
558 {
559 return (4 * MScore::division) / denominator();
560 }
561
562 }
563
564