Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2025 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "tuplethandler.h"
24 :
25 : #include "engraving/dom/factory.h"
26 : #include "engraving/dom/measure.h"
27 : #include "engraving/dom/tuplet.h"
28 : #include "engraving/types/fraction.h"
29 :
30 : using namespace mu::engraving;
31 : namespace mu::iex::tabledit {
32 : // start/stop tuplet and calculate timing correction
33 : // for a triplet of quarters, the length of each note is 2/3 * 1/4 = 1/6
34 : // TablEdit uses 1/8 instead, required next note position correction
35 : // is 1/6 - 1/8 = 4/24 - 3/24 = 1/24
36 :
37 382 : Fraction TupletHandler::doTuplet(const TefNote* const tefNote)
38 : {
39 382 : Fraction res { 0, 1 };
40 382 : Fraction correction { tefNote->length, 64 };
41 382 : correction *= { 1, 6 };
42 : LOGN("position %d string %d fret %d length %d triplet %d",
43 : tefNote->position, tefNote->string, tefNote->fret, tefNote->length, tefNote->triplet);
44 : LOGN("before inTuplet %d count %d totalLength %d", inTuplet, count, totalLength);
45 382 : if (tefNote->triplet) {
46 10 : if (!inTuplet) {
47 : LOGN("start triplet");
48 : }
49 10 : inTuplet = true;
50 10 : res = Fraction { totalLength, 2 * 3 * 64 };
51 : LOGN("res %d/%d", res.numerator(), res.denominator());
52 10 : ++count;
53 10 : totalLength += tefNote->length;
54 : LOGN("totalLength %d", totalLength);
55 : }
56 382 : if (!tefNote->triplet || (inTuplet && (totalLength % 3) == 0)) {
57 376 : if (inTuplet) {
58 : LOGN("stop triplet");
59 4 : const Fraction l { totalLength, 3 * 64 };
60 : LOGN("baselen %d/%d", l.numerator(), l.denominator());
61 4 : tuplet->setBaseLen(l);
62 : }
63 376 : inTuplet = false;
64 376 : count = 0;
65 376 : totalLength = 0;
66 : }
67 : LOGN("after inTuplet %d count %d totalLength %d res %d/%d", inTuplet, count, totalLength, res.numerator(), res.denominator());
68 382 : return res;
69 : }
70 :
71 : // add ChordRest to tuplet
72 : // needs measure, track and ratio
73 :
74 362 : void TupletHandler::addCr(Measure* measure, ChordRest* cr)
75 : {
76 362 : if (inTuplet && !tuplet) {
77 4 : tuplet = Factory::createTuplet(measure);
78 : LOGN("new tuplet %p cr ticks %d/%d", tuplet, cr->ticks().numerator(), cr->ticks().denominator());
79 4 : tuplet->setTrack(cr->track());
80 4 : tuplet->setTick(cr->tick());
81 4 : tuplet->setRatio({ 3, 2 });
82 : }
83 362 : if (tuplet) {
84 : LOGN("add cr to tuplet %p", tuplet);
85 10 : cr->setTuplet(tuplet);
86 10 : tuplet->add(cr);
87 : }
88 362 : if (!inTuplet) {
89 356 : tuplet = nullptr;
90 : }
91 : LOGN("tuplet %p", tuplet);
92 362 : }
93 : } // namespace mu::iex::tabledit
|