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