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