1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2011 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 "config.h"
14 #include "score.h"
15 #include "page.h"
16 #include "segment.h"
17 #include "clef.h"
18 #include "utils.h"
19 #include "system.h"
20 #include "measure.h"
21 #include "pitchspelling.h"
22 #include "chordrest.h"
23 #include "part.h"
24 #include "staff.h"
25 #include "note.h"
26 #include "chord.h"
27 #include "key.h"
28 #include "sig.h"
29 #include "tuplet.h"
30 #include "sym.h"
31 
32 namespace Ms {
33 
34 //---------------------------------------------------------
35 //   handleRect
36 //---------------------------------------------------------
37 
handleRect(const QPointF & pos)38 QRectF handleRect(const QPointF& pos)
39       {
40       return QRectF(pos.x()-4, pos.y()-4, 8, 8);
41       }
42 
43 //---------------------------------------------------------
44 //   tick2measure
45 //---------------------------------------------------------
46 
tick2measure(const Fraction & tick) const47 Measure* Score::tick2measure(const Fraction& tick) const
48       {
49       if (tick == Fraction(-1,1))   // special number
50             return lastMeasure();
51       if (tick <= Fraction(0,1))
52             return firstMeasure();
53 
54       Measure* lm = 0;
55       for (Measure* m = firstMeasure(); m; m = m->nextMeasure()) {
56             if (tick < m->tick()) {
57                   Q_ASSERT(lm);
58                   return lm;
59                   }
60             lm = m;
61             }
62       // check last measure
63       if (lm && (tick >= lm->tick()) && (tick <= lm->endTick()))
64             return lm;
65       qDebug("tick2measure %d (max %d) not found", tick.ticks(), lm ? lm->tick().ticks() : -1);
66       return 0;
67       }
68 
69 //---------------------------------------------------------
70 //   tick2measureMM
71 //---------------------------------------------------------
72 
tick2measureMM(const Fraction & t) const73 Measure* Score::tick2measureMM(const Fraction& t) const
74       {
75       Fraction tick(t);
76       if (tick == Fraction(-1,1))
77             return lastMeasureMM();
78       if (tick < Fraction(0,1))
79             tick = Fraction(0,1);
80 
81       Measure* lm = 0;
82 
83       for (Measure* m = firstMeasureMM(); m; m = m->nextMeasureMM()) {
84             if (tick < m->tick()) {
85                   Q_ASSERT(lm);
86                   return lm;
87                   }
88             lm = m;
89             }
90       // check last measure
91       if (lm && (tick >= lm->tick()) && (tick <= lm->endTick()))
92             return lm;
93       qDebug("tick2measureMM %d (max %d) not found", tick.ticks(), lm ? lm->tick().ticks() : -1);
94       return 0;
95       }
96 
97 //---------------------------------------------------------
98 //   tick2measureBase
99 //---------------------------------------------------------
100 
tick2measureBase(const Fraction & tick) const101 MeasureBase* Score::tick2measureBase(const Fraction& tick) const
102       {
103       for (MeasureBase* mb = first(); mb; mb = mb->next()) {
104             Fraction st = mb->tick();
105             Fraction l  = mb->ticks();
106             if (tick >= st && tick < (st+l))
107                   return mb;
108             }
109 //      qDebug("tick2measureBase %d not found", tick);
110       return 0;
111       }
112 
113 //---------------------------------------------------------
114 //   tick2segment
115 //---------------------------------------------------------
116 
tick2segmentMM(const Fraction & tick,bool first,SegmentType st) const117 Segment* Score::tick2segmentMM(const Fraction& tick, bool first, SegmentType st) const
118       {
119       return tick2segment(tick,first,st,true);
120       }
121 
tick2segmentMM(const Fraction & tick) const122 Segment* Score::tick2segmentMM(const Fraction& tick) const
123       {
124       return tick2segment(tick, false, SegmentType::All, true);
125       }
tick2segmentMM(const Fraction & tick,bool first) const126 Segment* Score::tick2segmentMM(const Fraction& tick, bool first) const
127       {
128       return tick2segment(tick, first, SegmentType::All, true);
129       }
130 
tick2segment(const Fraction & t,bool first,SegmentType st,bool useMMrest) const131 Segment* Score::tick2segment(const Fraction& t, bool first, SegmentType st, bool useMMrest ) const
132       {
133       Fraction tick(t);
134       Measure* m;
135       if (useMMrest) {
136             m = tick2measureMM(tick);
137             // When mmRest force tick to the first segment of mmRest.
138             if (m && m->isMMRest() && tick != m->endTick())
139                   tick = m->tick();
140             }
141       else
142             m = tick2measure(tick);
143 
144       if (m == 0) {
145             qDebug("no measure for tick %d", tick.ticks());
146             return 0;
147             }
148       for (Segment* segment   = m->first(st); segment;) {
149             Fraction t1       = segment->tick();
150             Segment* nsegment = segment->next(st);
151             if (tick == t1) {
152                   if (first)
153                         return segment;
154                   else {
155                         if (!nsegment || tick < nsegment->tick())
156                               return segment;
157                         }
158                   }
159             segment = nsegment;
160             }
161       qDebug("no segment for tick %d (start search at %d (measure %d))", tick.ticks(), t.ticks(), m->tick().ticks());
162       return 0;
163       }
164 
tick2segment(const Fraction & tick) const165 Segment* Score::tick2segment(const Fraction& tick) const
166       {
167       return tick2segment(tick, false, SegmentType::All, false);
168       }
169 
tick2segment(const Fraction & tick,bool first) const170 Segment* Score::tick2segment(const Fraction& tick, bool first) const
171       {
172       return tick2segment(tick, first, SegmentType::All, false);
173       }
174 
175 //---------------------------------------------------------
176 //   tick2leftSegment
177 /// return the segment at this tick position if any or
178 /// the first segment *before* this tick position
179 //---------------------------------------------------------
180 
tick2leftSegment(const Fraction & tick,bool useMMrest) const181 Segment* Score::tick2leftSegment(const Fraction& tick, bool useMMrest) const
182       {
183       Measure* m = useMMrest ? tick2measureMM(tick) : tick2measure(tick);
184       if (m == 0) {
185             qDebug("tick2leftSegment(): not found tick %d", tick.ticks());
186             return 0;
187             }
188       // loop over all segments
189       Segment* ps = 0;
190       for (Segment* s = m->first(SegmentType::ChordRest); s; s = s->next(SegmentType::ChordRest)) {
191             if (tick < s->tick())
192                   return ps;
193             else if (tick == s->tick())
194                   return s;
195             ps = s;
196             }
197       return ps;
198       }
199 
200 //---------------------------------------------------------
201 //   tick2rightSegment
202 /// return the segment at this tick position if any or
203 /// the first segment *after* this tick position
204 //---------------------------------------------------------
205 
tick2rightSegment(const Fraction & tick,bool useMMrest) const206 Segment* Score::tick2rightSegment(const Fraction& tick, bool useMMrest) const
207       {
208       Measure* m = useMMrest ? tick2measureMM(tick) : tick2measure(tick);
209       if (m == 0) {
210             qDebug("tick2nearestSegment(): not found tick %d", tick.ticks());
211             return 0;
212             }
213       // loop over all segments
214       for (Segment* s = m->first(SegmentType::ChordRest); s; s = s->next1(SegmentType::ChordRest)) {
215             if (tick <= s->tick())
216                   return s;
217             }
218       return 0;
219       }
220 
221 //---------------------------------------------------------
222 //   tick2beatType
223 //---------------------------------------------------------
224 
tick2beatType(const Fraction & tick)225 BeatType Score::tick2beatType(const Fraction& tick)
226       {
227       Measure* m = tick2measure(tick);
228       Fraction msrTick = m->tick();
229       TimeSigFrac timeSig = sigmap()->timesig(msrTick).nominal();
230 
231       int rtick = (tick - msrTick).ticks();
232 
233       if (m->isAnacrusis()) // measure is incomplete (anacrusis)
234             rtick += timeSig.ticksPerMeasure() - m->ticks().ticks();
235 
236       return timeSig.rtick2beatType(rtick);
237       }
238 
239 //---------------------------------------------------------
240 //   getStaff
241 //---------------------------------------------------------
242 
getStaff(System * system,const QPointF & p)243 int getStaff(System* system, const QPointF& p)
244       {
245       QPointF pp = p - system->page()->pos() - system->pos();
246       for (int i = 0; i < system->page()->score()->nstaves(); ++i) {
247             qreal sp = system->spatium();
248             QRectF r = system->bboxStaff(i).adjusted(0.0, -sp, 0.0, sp);
249             if (r.contains(pp))
250                   return i;
251             }
252       return -1;
253       }
254 
255 //---------------------------------------------------------
256 //   nextSeg
257 //---------------------------------------------------------
258 
nextSeg(const Fraction & tick,int track)259 Fraction Score::nextSeg(const Fraction& tick, int track)
260       {
261       Segment* seg = tick2segment(tick);
262       while (seg) {
263             seg = seg->next1(SegmentType::ChordRest);
264             if (seg == 0)
265                   break;
266             if (seg->element(track))
267                   break;
268             }
269       return seg ? seg->tick() : Fraction(-1,1);
270       }
271 
272 //---------------------------------------------------------
273 //   nextSeg1
274 //---------------------------------------------------------
275 
nextSeg1(Segment * seg,int & track)276 Segment* nextSeg1(Segment* seg, int& track)
277       {
278       int staffIdx   = track / VOICES;
279       int startTrack = staffIdx * VOICES;
280       int endTrack   = startTrack + VOICES;
281       while ((seg = seg->next1(SegmentType::ChordRest))) {
282             for (int t = startTrack; t < endTrack; ++t) {
283                   if (seg->element(t)) {
284                         track = t;
285                         return seg;
286                         }
287                   }
288             }
289       return 0;
290       }
291 
292 //---------------------------------------------------------
293 //   prevSeg1
294 //---------------------------------------------------------
295 
prevSeg1(Segment * seg,int & track)296 Segment* prevSeg1(Segment* seg, int& track)
297       {
298       int staffIdx   = track / VOICES;
299       int startTrack = staffIdx * VOICES;
300       int endTrack   = startTrack + VOICES;
301       while ((seg = seg->prev1(SegmentType::ChordRest))) {
302             for (int t = startTrack; t < endTrack; ++t) {
303                   if (seg->element(t)) {
304                         track = t;
305                         return seg;
306                         }
307                   }
308             }
309       return 0;
310       }
311 
312 //---------------------------------------------------------
313 //    next/prevChordNote
314 //
315 //    returns the top note of the next/previous chord. If a
316 //    chord exists in the same track as note,
317 //    it is used. If not, the topmost existing chord is used.
318 //    May return nullptr if there is no next/prev note
319 //---------------------------------------------------------
320 
nextChordNote(Note * note)321 Note* nextChordNote(Note* note)
322       {
323       int         track       = note->track();
324       int         fromTrack   = (track / VOICES) * VOICES;
325       int         toTrack     = fromTrack + VOICES;
326       // TODO : limit to same instrument, not simply to same staff!
327       Segment*    seg   = note->chord()->segment()->nextCR(track, true);
328       while (seg) {
329             Element*    targetElement = seg->elementAt(track);
330             // if a chord exists in the same track, return its top note
331             if (targetElement && targetElement->isChord())
332                   return toChord(targetElement)->upNote();
333             // if not, return topmost chord in track range
334             for (int i = fromTrack ; i < toTrack; i++) {
335                   targetElement = seg->elementAt(i);
336                   if (targetElement && targetElement->isChord())
337                         return toChord(targetElement)->upNote();
338                   }
339             seg = seg->nextCR(track, true);
340             }
341       return nullptr;
342       }
343 
prevChordNote(Note * note)344 Note* prevChordNote(Note* note)
345       {
346       int         track       = note->track();
347       int         fromTrack   = (track / VOICES) * VOICES;
348       int         toTrack     = fromTrack + VOICES;
349       // TODO : limit to same instrument, not simply to same staff!
350       Segment*    seg   = note->chord()->segment()->prev1();
351       while (seg) {
352             if (seg->segmentType() == SegmentType::ChordRest) {
353                   Element*    targetElement = seg->elementAt(track);
354                   // if a chord exists in the same track, return its top note
355                   if (targetElement && targetElement->isChord())
356                         return toChord(targetElement)->upNote();
357                   // if not, return topmost chord in track range
358                   for (int i = fromTrack ; i < toTrack; i++) {
359                         targetElement = seg->elementAt(i);
360                         if (targetElement && targetElement->isChord())
361                               return toChord(targetElement)->upNote();
362                         }
363                   }
364             seg = seg->prev1();
365             }
366       return nullptr;
367       }
368 
369 //---------------------------------------------------------
370 //   pitchKeyAdjust
371 //    change entered note to sounding pitch dependent
372 //    on key.
373 //    Example: if F is entered in G-major, a Fis is played
374 //    key -7 ... +7
375 //---------------------------------------------------------
376 
pitchKeyAdjust(int step,Key key)377 int pitchKeyAdjust(int step, Key key)
378       {
379       static int ptab[15][7] = {
380 //             c  d  e  f  g   a  b
381             { -1, 1, 3, 4, 6,  8, 10 },     // Bes
382             { -1, 1, 3, 5, 6,  8, 10 },     // Ges
383             {  0, 1, 3, 5, 6,  8, 10 },     // Des
384             {  0, 1, 3, 5, 7,  8, 10 },     // As
385             {  0, 2, 3, 5, 7,  8, 10 },     // Es
386             {  0, 2, 3, 5, 7,  9, 10 },     // B
387             {  0, 2, 4, 5, 7,  9, 10 },     // F
388             {  0, 2, 4, 5, 7,  9, 11 },     // C
389             {  0, 2, 4, 6, 7,  9, 11 },     // G
390             {  1, 2, 4, 6, 7,  9, 11 },     // D
391             {  1, 2, 4, 6, 8,  9, 11 },     // A
392             {  1, 3, 4, 6, 8,  9, 11 },     // E
393             {  1, 3, 4, 6, 8, 10, 11 },     // H
394             {  1, 3, 5, 6, 8, 10, 11 },     // Fis
395             {  1, 3, 5, 6, 8, 10, 12 },     // Cis
396             };
397       return ptab[int(key)+7][step];
398       }
399 
400 //---------------------------------------------------------
401 //   y2pitch
402 //---------------------------------------------------------
403 
y2pitch(qreal y,ClefType clef,qreal _spatium)404 int y2pitch(qreal y, ClefType clef, qreal _spatium)
405       {
406       int l = lrint(y / _spatium * 2.0);
407       return line2pitch(l, clef, Key::C);
408       }
409 
410 //---------------------------------------------------------
411 //   line2pitch
412 //    key  -7 ... +7
413 //---------------------------------------------------------
414 
line2pitch(int line,ClefType clef,Key key)415 int line2pitch(int line, ClefType clef, Key key)
416       {
417       int l      = ClefInfo::pitchOffset(clef) - line;
418       int octave = 0;
419       while (l < 0) {
420             l += 7;
421             octave++;
422             }
423       octave += l / 7;
424       l       = l % 7;
425 
426       int pitch = pitchKeyAdjust(l, key) + octave * 12;
427 
428       if (pitch > 127)
429             pitch = 127;
430       else if (pitch < 0)
431             pitch = 0;
432       return pitch;
433       }
434 
435 //---------------------------------------------------------
436 //   quantizeLen
437 //---------------------------------------------------------
438 
quantizeLen(int len,int raster)439 int quantizeLen(int len, int raster)
440       {
441       if (raster == 0)
442             return len;
443       return int( ((float)len/raster) + 0.5 ) * raster; //round to the closest multiple of raster
444       }
445 
446 static const char* vall[] = {
447       QT_TRANSLATE_NOOP("utils", "c"),
448       QT_TRANSLATE_NOOP("utils", "c♯"),
449       QT_TRANSLATE_NOOP("utils", "d"),
450       QT_TRANSLATE_NOOP("utils", "d♯"),
451       QT_TRANSLATE_NOOP("utils", "e"),
452       QT_TRANSLATE_NOOP("utils", "f"),
453       QT_TRANSLATE_NOOP("utils", "f♯"),
454       QT_TRANSLATE_NOOP("utils", "g"),
455       QT_TRANSLATE_NOOP("utils", "g♯"),
456       QT_TRANSLATE_NOOP("utils", "a"),
457       QT_TRANSLATE_NOOP("utils", "a♯"),
458       QT_TRANSLATE_NOOP("utils", "b")
459       };
460 static const char* valu[] = {
461       QT_TRANSLATE_NOOP("utils", "C"),
462       QT_TRANSLATE_NOOP("utils", "C♯"),
463       QT_TRANSLATE_NOOP("utils", "D"),
464       QT_TRANSLATE_NOOP("utils", "D♯"),
465       QT_TRANSLATE_NOOP("utils", "E"),
466       QT_TRANSLATE_NOOP("utils", "F"),
467       QT_TRANSLATE_NOOP("utils", "F♯"),
468       QT_TRANSLATE_NOOP("utils", "G"),
469       QT_TRANSLATE_NOOP("utils", "G♯"),
470       QT_TRANSLATE_NOOP("utils", "A"),
471       QT_TRANSLATE_NOOP("utils", "A♯"),
472       QT_TRANSLATE_NOOP("utils", "B")
473       };
474 
475 /*!
476  * Returns the string representation of the given pitch.
477  *
478  * Returns the latin letter name, accidental, and octave numeral.
479  * Uses upper case only for pitches 0-24.
480  *
481  * @param v
482  *  The pitch number of the note.
483  *
484  * @return
485  *  The string representation of the note.
486  */
pitch2string(int v)487 QString pitch2string(int v)
488       {
489       if (v < 0 || v > 127)
490             return QString("----");
491       int octave = (v / 12) - 1;
492       QString o;
493       o = QString::asprintf("%d", octave);
494       int i = v % 12;
495       return qApp->translate("utils", octave < 0 ? valu[i] : vall[i]) + o;
496       }
497 
498 /*!
499  * An array of all supported interval sorted by size.
500  *
501  * Because intervals can be spelled differently, this array
502  * tracks all the different valid intervals. They are arranged
503  * in diatonic then chromatic order.
504  */
505 Interval intervalList[intervalListSize] = {
506       // diatonic - chromatic
507       Interval(0, 0),         //  0 Perfect Unison
508       Interval(0, 1),         //  1 Augmented Unison
509 
510       Interval(1, 0),         //  2 Diminished Second
511       Interval(1, 1),         //  3 Minor Second
512       Interval(1, 2),         //  4 Major Second
513       Interval(1, 3),         //  5 Augmented Second
514 
515       Interval(2, 2),         //  6 Diminished Third
516       Interval(2, 3),         //  7 Minor Third
517       Interval(2, 4),         //  8 Major Third
518       Interval(2, 5),         //  9 Augmented Third
519 
520       Interval(3, 4),         // 10 Diminished Fourth
521       Interval(3, 5),         // 11 Perfect Fourth
522       Interval(3, 6),         // 12 Augmented Fourth
523 
524       Interval(4, 6),         // 13 Diminished Fifth
525       Interval(4, 7),         // 14 Perfect Fifth
526       Interval(4, 8),         // 15 Augmented Fifth
527 
528       Interval(5, 7),         // 16 Diminished Sixth
529       Interval(5, 8),         // 17 Minor Sixth
530       Interval(5, 9),         // 18 Major Sixth
531       Interval(5, 10),        // 19 Augmented Sixth
532 
533       Interval(6, 9),         // 20 Diminished Seventh
534       Interval(6, 10),        // 21 Minor Seventh
535       Interval(6, 11),        // 22 Major Seventh
536       Interval(6, 12),        // 23 Augmented Seventh
537 
538       Interval(7, 11),        // 24 Diminshed Octave
539       Interval(7, 12)         // 25 Perfect Octave
540       };
541 
542 /*!
543  * Finds the most likely diatonic interval for a semitone distance.
544  *
545  * Uses the most common diatonic intervals.
546  *
547  * @param
548  *  The number of semitones in the chromatic interval.
549  *  Negative semitones will simply be made positive.
550  *
551  * @return
552  *  The number of diatonic steps in the interval.
553  */
554 
chromatic2diatonic(int semitones)555 int chromatic2diatonic(int semitones)
556       {
557       static int il[12] = {
558             0,    // Perfect Unison
559             3,    // Minor Second
560             4,    // Major Second
561             7,    // Minor Third
562             8,    // Major Third
563             11,   // Perfect Fourth
564             12,   // Augmented Fourth
565             14,   // Perfect Fifth
566             17,   // Minor Sixth
567             18,   // Major Sixth
568             21,   // Minor Seventh
569             22,   // Major Seventh
570             // 25    Perfect Octave
571             };
572       bool down = semitones < 0;
573       if (down)
574             semitones = -semitones;
575       int val = semitones % 12;
576       int octave = semitones / 12;
577       int intervalIndex = il[val];
578       int steps = intervalList[intervalIndex].diatonic;
579       steps = steps + octave * 7;
580       return down ? -steps : steps;
581       }
582 
583 //---------------------------------------------------------
584 //   searchInterval
585 //---------------------------------------------------------
586 
searchInterval(int steps,int semitones)587 int searchInterval(int steps, int semitones)
588       {
589       unsigned n = sizeof(intervalList)/sizeof(*intervalList);
590       for (unsigned i = 0; i < n; ++i) {
591             if ((intervalList[i].diatonic == steps) && (intervalList[i].chromatic == semitones))
592                   return i;
593             }
594       return -1;
595       }
596 
597 static int _majorVersion, _minorVersion, _updateVersion;
598 
599 /*!
600  * Returns the program version
601  *
602  * @return
603  *  Version in the format: MMmmuu
604  *  Where M=Major, m=minor, and u=update
605  */
606 
version()607 int version()
608       {
609       QRegExp re("(\\d+)\\.(\\d+)\\.(\\d+)");
610       if (re.indexIn(VERSION) != -1) {
611             QStringList sl = re.capturedTexts();
612             if (sl.size() == 4) {
613                   _majorVersion = sl[1].toInt();
614                   _minorVersion = sl[2].toInt();
615                   _updateVersion = sl[3].toInt();
616                   return _majorVersion * 10000 + _minorVersion * 100 + _updateVersion;
617                   }
618             }
619       return 0;
620       }
621 
622 //---------------------------------------------------------
623 //   majorVersion
624 //---------------------------------------------------------
625 
majorVersion()626 int majorVersion()
627       {
628       version();
629       return _majorVersion;
630       }
631 
632 //---------------------------------------------------------
633 //   minorVersion
634 //---------------------------------------------------------
635 
minorVersion()636 int minorVersion()
637       {
638       version();
639       return _minorVersion;
640       }
641 
642 //---------------------------------------------------------
643 //   updateVersion
644 //---------------------------------------------------------
645 
updateVersion()646 int updateVersion()
647       {
648       version();
649       return _updateVersion;
650       }
651 
652 //---------------------------------------------------------
653 //   updateVersion
654 ///  Up to 4 digits X.X.X.X
655 ///  Each digit can be double XX.XX.XX.XX
656 ///  return true if v1 < v2
657 //---------------------------------------------------------
658 
compareVersion(QString v1,QString v2)659 bool compareVersion(QString v1, QString v2)
660       {
661       auto v1l = v1.split(".");
662       auto v2l = v2.split(".");
663       int ma = qPow(100,qMax(v1l.size(), v2l.size()));
664       int m = ma;
665       int vv1 = 0;
666       for (int i = 0; i < v1l.size(); i++) {
667             vv1 += (m * v1l[i].toInt());
668             m /= 100;
669             }
670       m = ma;
671       int vv2 = 0;
672       for (int i = 0; i < v2l.size(); i++) {
673             vv2 += (m * v2l[i].toInt());
674             m /= 100;
675             }
676 
677       return vv1 < vv2;
678       }
679 
680 //---------------------------------------------------------
681 //   diatonicUpDown
682 //    used to find the second note of a trill, mordent etc.
683 //    key  -7 ... +7
684 //---------------------------------------------------------
685 
diatonicUpDown(Key k,int pitch,int steps)686 int diatonicUpDown(Key k, int pitch, int steps)
687       {
688       static int ptab[15][7] = {
689 //             c  c#   d  d#    e   f  f#   g  g#  a  a#   b
690             { -1,      1,       3,  4,      6,     8,      10 },     // Cb Ces
691             { -1,      1,       3,  5,      6,     8,      10 },     // Gb Ges
692             {  0,      1,       3,  5,      6,     8,      10 },     // Db Des
693             {  0,      1,       3,  5,      7,     8,      10 },     // Ab As
694             {  0,      2,       3,  5,      7,     8,      10 },     // Eb Es
695             {  0,      2,       3,  5,      7,     9,      10 },     // Bb B
696             {  0,      2,       4,  5,      7,     9,      10 },     // F  F
697 
698             {  0,      2,       4,  5,      7,     9,      11 },     // C  C
699 
700             {  0,      2,       4,  6,      7,     9,      11 },     // G  G
701             {  1,      2,       4,  6,      7,     9,      11 },     // D  D
702             {  1,      2,       4,  6,      8,     9,      11 },     // A  A
703             {  1,      3,       4,  6,      8,     9,      11 },     // E  E
704             {  1,      3,       4,  6,      8,    10,      11 },     // B  H
705             {  1,      3,       5,  6,      8,    10,      11 },     // F# Fis
706             {  1,      3,       5,  6,      8,    10,      12 },     // C# Cis
707             };
708 
709       int key    = int(k) + 7;
710       int step   = pitch % 12;
711       int octave = pitch / 12;
712 
713       // loop through the diatonic steps of the key looking for the given note
714       // or the gap where it would fit
715       int i = 0;
716       while (i < 7) {
717             if (ptab[key][i] >= step)
718                   break;
719             ++i;
720             }
721 
722       // neither step nor gap found
723       // reset to beginning
724       if (i == 7) {
725             ++octave;
726             i = 0;
727             }
728       // if given step not found (gap found instead), and we are stepping up
729       // then we've already accounted for one step
730       if (ptab[key][i] > step && steps > 0)
731             --steps;
732 
733       // now start counting diatonic steps up or down
734       if (steps > 0) {
735             // count up
736             while (steps--) {
737                   ++i;
738                   if (i == 7) {
739                         // hit last step; reset to beginning
740                         ++octave;
741                         i = 0;
742                         }
743                   }
744             }
745       else if (steps < 0) {
746             // count down
747             while (steps++) {
748                   --i;
749                   if (i < 0) {
750                         // hit first step; reset to end
751                         --octave;
752                         i = 6;
753                         }
754                   }
755             }
756 
757       // convert step to pitch
758       step = ptab[key][i];
759       pitch = octave * 12 + step;
760       if (pitch < 0)
761             pitch = 0;
762       if (pitch > 127)
763             pitch = 128;
764       return pitch;
765       }
766 
767 //---------------------------------------------------------
768 //   searchTieNote
769 //    search Note to tie to "note"
770 //---------------------------------------------------------
771 
searchTieNote(Note * note)772 Note* searchTieNote(Note* note)
773       {
774       if (!note)
775             return nullptr;
776 
777       Note* note2  = 0;
778       Chord* chord = note->chord();
779       Segment* seg = chord->segment();
780       Part* part   = chord->part();
781       int strack   = part->staves()->front()->idx() * VOICES;
782       int etrack   = strack + part->staves()->size() * VOICES;
783 
784       if (chord->isGraceBefore()) {
785             chord = toChord(chord->parent());
786 
787             // try to tie to next grace note
788 
789             int index = note->chord()->graceIndex();
790             for (Chord* c : chord->graceNotes()) {
791                   if (c->graceIndex() == index + 1) {
792                         note2 = c->findNote(note->pitch());
793                         if (note2) {
794 //printf("found grace-grace tie\n");
795                               return note2;
796                               }
797                         }
798                   }
799 
800             // try to tie to note in parent chord
801             note2 = chord->findNote(note->pitch());
802             if (note2)
803                   return note2;
804             }
805       else if (chord->isGraceAfter()) {
806             // grace after
807             // we will try to tie to note in next normal chord, below
808             // meanwhile, set chord to parent chord so the endTick calculation will make sense
809             chord = toChord(chord->parent());
810             }
811       else {
812             // normal chord
813             // try to tie to grace note after if present
814             QVector<Chord*> gna = chord->graceNotesAfter();
815             if (!gna.empty()) {
816                   Chord* gc = gna[0];
817                   note2 = gc->findNote(note->pitch());
818                   if (note2)
819                         return note2;
820                   }
821             }
822       // at this point, chord is a regular chord, not a grace chord
823       // and we are looking for a note in the *next* chord (grace or regular)
824 
825       // calculate end of current note duration
826       // but err on the safe side in case there is roundoff in tick count
827       Fraction endTick = chord->tick() + chord->actualTicks() - Fraction(1, 4 * 480);
828 
829       int idx1 = note->unisonIndex();
830       while ((seg = seg->next1(SegmentType::ChordRest))) {
831             // skip ahead to end of current note duration as calculated above
832             // but just in case, stop if we find element in current track
833             if (seg->tick() < endTick  && !seg->element(chord->track()))
834                   continue;
835             for (int track = strack; track < etrack; ++track) {
836                   Element* e = seg->element(track);
837                   if (e == 0 || !e->isChord())
838                         continue;
839                   Chord* c = toChord(e);
840                   const int staffIdx = c->staffIdx() + c->staffMove();
841                   if (staffIdx != chord->staffIdx() + chord->staffMove()) {
842                         // this check is needed as we are iterating over all staves to capture cross-staff chords
843                         continue;
844                         }
845                   // if there are grace notes before, try to tie to first one
846                   QVector<Chord*> gnb = c->graceNotesBefore();
847                   if (!gnb.empty()) {
848                         Chord* gc = gnb[0];
849                         Note* gn2 = gc->findNote(note->pitch());
850                         if (gn2)
851                               return gn2;
852                         }
853                   int idx2 = 0;
854                   for (Note* n : c->notes()) {
855                         if (n->pitch() == note->pitch()) {
856                               if (idx1 == idx2) {
857                                     if (note2 == 0 || c->track() == chord->track()) {
858                                           note2 = n;
859                                           break;
860                                           }
861                                     }
862                               else
863                                     ++idx2;
864                               }
865                         }
866                   }
867             if (note2)
868                   break;
869             }
870       return note2;
871       }
872 
873 //---------------------------------------------------------
874 //   searchTieNote114
875 //    search Note to tie to "note", tie to next note in
876 //    same voice
877 //---------------------------------------------------------
878 
searchTieNote114(Note * note)879 Note* searchTieNote114(Note* note)
880       {
881       Note* note2  = 0;
882       Chord* chord = note->chord();
883       Segment* seg = chord->segment();
884       Part* part   = chord->part();
885       int strack   = part->staves()->front()->idx() * VOICES;
886       int etrack   = strack + part->staves()->size() * VOICES;
887 
888       while ((seg = seg->next1(SegmentType::ChordRest))) {
889             for (int track = strack; track < etrack; ++track) {
890                   Element* e = seg->element(track);
891                   if (e == 0 || (!e->isChord()) || (e->track() != chord->track()))
892                         continue;
893                   Chord* c = toChord(e);
894                   int staffIdx = c->staffIdx() + c->staffMove();
895                   if (staffIdx != chord->staffIdx() + chord->staffMove())  // cannot happen?
896                         continue;
897                   for (Note* n : c->notes()) {
898                         if (n->pitch() == note->pitch()) {
899                               if (note2 == 0 || c->track() == chord->track())
900                                     note2 = n;
901                               }
902                         }
903                   }
904             if (note2)
905                   break;
906             }
907       return note2;
908       }
909 
910 //---------------------------------------------------------
911 //   absStep
912 ///   Compute absolute step.
913 ///   C D E F G A B ....
914 //---------------------------------------------------------
915 
absStep(int tpc,int pitch)916 int absStep(int tpc, int pitch)
917       {
918       int line     = tpc2step(tpc) + (pitch / 12) * 7;
919       int tpcPitch = tpc2pitch(tpc);
920 
921       if (tpcPitch < 0)
922             line += 7;
923       else
924             line -= (tpcPitch / 12) * 7;
925       return line;
926       }
927 
absStep(int pitch)928 int absStep(int pitch)
929       {
930       // TODO - does this need to be key-aware?
931       int tpc = pitch2tpc(pitch, Key::C, Prefer::NEAREST);
932       return absStep(tpc, pitch);
933       }
934 
absStep(int line,ClefType clef)935 int absStep(int line, ClefType clef)
936       {
937       return ClefInfo::pitchOffset(clef) - line;
938       }
939 
940 //---------------------------------------------------------
941 //   relStep
942 ///   Compute relative step from absolute step
943 ///   which depends on actual clef. Step 0 starts on the
944 ///   first (top) staff line.
945 //---------------------------------------------------------
946 
relStep(int line,ClefType clef)947 int relStep(int line, ClefType clef)
948       {
949       return ClefInfo::pitchOffset(clef) - line;
950       }
951 
relStep(int pitch,int tpc,ClefType clef)952 int relStep(int pitch, int tpc, ClefType clef)
953       {
954       return relStep(absStep(tpc, pitch), clef);
955       }
956 
957 //---------------------------------------------------------
958 //   pitch2step
959 //   returns one of { 0, 1, 2, 3, 4, 5, 6 }
960 //---------------------------------------------------------
961 
pitch2step(int pitch)962 int pitch2step(int pitch)
963       {
964       //                            C  C# D  D# E  F  F# G  G# A  A# B
965       static const char tab[12] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
966       return tab[pitch%12];
967       }
968 
969 //---------------------------------------------------------
970 //   step2pitch
971 //   returns one of { 0, 2, 4, 5, 7, 9, 11 }
972 //---------------------------------------------------------
973 
step2pitch(int step)974 int step2pitch(int step)
975       {
976       static const char tab[7] = { 0, 2, 4, 5, 7, 9, 11 };
977       return tab[step % 7];
978       }
979 
980 //---------------------------------------------------------
981 //   skipTuplet
982 //    return segment of rightmost chord/rest in a
983 //    (possible nested) tuplet
984 //---------------------------------------------------------
985 
skipTuplet(Tuplet * tuplet)986 Segment* skipTuplet(Tuplet* tuplet)
987       {
988       DurationElement* nde = tuplet->elements().back();
989       while (nde->isTuplet()) {
990             tuplet = toTuplet(nde);
991             nde = tuplet->elements().back();
992             }
993       return toChordRest(nde)->segment();
994       }
995 
996 //---------------------------------------------------------
997 //   toTimeSigString
998 //    replace ascii with bravura symbols
999 //---------------------------------------------------------
1000 
toTimeSigString(const QString & s)1001 std::vector<SymId> toTimeSigString(const QString& s)
1002       {
1003       struct Dict {
1004             QChar code;
1005             SymId id;
1006             };
1007       static const std::vector<Dict> dict = {
1008             { 43,    SymId::timeSigPlusSmall        },  // '+'
1009             { 48,    SymId::timeSig0                },  // '0'
1010             { 49,    SymId::timeSig1                },  // '1'
1011             { 50,    SymId::timeSig2                },  // '2'
1012             { 51,    SymId::timeSig3                },  // '3'
1013             { 52,    SymId::timeSig4                },  // '4'
1014             { 53,    SymId::timeSig5                },  // '5'
1015             { 54,    SymId::timeSig6                },  // '6'
1016             { 55,    SymId::timeSig7                },  // '7'
1017             { 56,    SymId::timeSig8                },  // '8'
1018             { 57,    SymId::timeSig9                },  // '9'
1019             { 67,    SymId::timeSigCommon           },  // 'C'
1020             { 40,    SymId::timeSigParensLeftSmall  },  // '('
1021             { 41,    SymId::timeSigParensRightSmall },  // ')'
1022             { 162,   SymId::timeSigCutCommon        },  // '¢'
1023             { 189,   SymId::timeSigFractionHalf     },
1024             { 188,   SymId::timeSigFractionQuarter  },
1025             { 59664, SymId::mensuralProlation1      },
1026             { 79,    SymId::mensuralProlation2      },  // 'O'
1027             { 59665, SymId::mensuralProlation2      },
1028             { 216,   SymId::mensuralProlation3      },  // 'Ø'
1029             { 59666, SymId::mensuralProlation3      },
1030             { 59667, SymId::mensuralProlation4      },
1031             { 59668, SymId::mensuralProlation5      },
1032             { 59670, SymId::mensuralProlation7      },
1033             { 59671, SymId::mensuralProlation8      },
1034             { 59673, SymId::mensuralProlation10     },
1035             { 59674, SymId::mensuralProlation11     },
1036             };
1037 
1038       std::vector<SymId> d;
1039       for (auto c : s) {
1040             for (const Dict& e : dict) {
1041                   if (c == e.code) {
1042                         d.push_back(e.id);
1043                         break;
1044                         }
1045                   }
1046             }
1047       return d;
1048       }
1049 
1050 //---------------------------------------------------------
1051 //   actualTicks
1052 //---------------------------------------------------------
1053 
actualTicks(Fraction duration,Tuplet * tuplet,Fraction timeStretch)1054 Fraction actualTicks(Fraction duration, Tuplet* tuplet, Fraction timeStretch)
1055       {
1056       Fraction f = duration / timeStretch;
1057       for (Tuplet* t = tuplet; t; t = t->tuplet())
1058             f /= t->ratio();
1059       return f;
1060       }
1061 
1062 }
1063 
1064