LCOV - code coverage report
Current view: top level - src/importexport/guitarpro/internal - utils.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 68.8 % 125 86
Test Date: 2026-11-05 04:07:02

            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) 2021 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              : #include "utils.h"
      23              : 
      24              : #include "realfn.h"
      25              : #include "engraving/dom/chord.h"
      26              : #include "engraving/dom/factory.h"
      27              : #include "engraving/dom/note.h"
      28              : #include "engraving/dom/parenthesis.h"
      29              : #include "engraving/dom/playcounttext.h"
      30              : #include "engraving/dom/score.h"
      31              : #include "engraving/dom/measure.h"
      32              : #include "engraving/dom/segment.h"
      33              : #include "engraving/style/styledef.h"
      34              : 
      35              : using namespace mu::engraving;
      36              : 
      37              : namespace mu::iex::guitarpro::utils {
      38           74 : int harmonicOvertone(Note* note, float harmonicValue, int harmonicType)
      39              : {
      40           74 :     int result{ 0 };
      41              : 
      42           74 :     if (muse::RealIsEqual(harmonicValue, 12.0f)) {
      43           56 :         result = 12;
      44           18 :     } else if (muse::RealIsEqual(harmonicValue, 7.0f) || muse::RealIsEqual(harmonicValue, 19.0f)) {
      45            2 :         result = 19;
      46           16 :     } else if (muse::RealIsEqual(harmonicValue, 5.0f) || muse::RealIsEqual(harmonicValue, 24.0f)) {
      47            3 :         result = 24;
      48           13 :     } else if (muse::RealIsEqual(harmonicValue, 3.9f)
      49           13 :                || muse::RealIsEqual(harmonicValue, 4.0f)
      50           10 :                || muse::RealIsEqual(harmonicValue, 9.0f)
      51           26 :                || muse::RealIsEqual(harmonicValue, 16.0f)) {
      52            3 :         result = 28;
      53           10 :     } else if (muse::RealIsEqual(harmonicValue, 3.2f)) {
      54            2 :         result = 31;
      55            8 :     } else if (muse::RealIsEqual(harmonicValue, 2.7f)
      56            6 :                || muse::RealIsEqual(harmonicValue, 5.8f)
      57            6 :                || muse::RealIsEqual(harmonicValue, 9.6f)
      58            6 :                || muse::RealIsEqual(harmonicValue, 14.7f)
      59           14 :                || muse::RealIsEqual(harmonicValue, 21.7f)) {
      60            4 :         result = 34;
      61            4 :     } else if (muse::RealIsEqual(harmonicValue, 2.3f)
      62            4 :                || muse::RealIsEqual(harmonicValue, 2.4f)
      63            0 :                || muse::RealIsEqual(harmonicValue, 8.2f)
      64            8 :                || muse::RealIsEqual(harmonicValue, 17.0f)) {
      65            4 :         result = 36;
      66            0 :     } else if (muse::RealIsEqual(harmonicValue, 2.0f)) {
      67            0 :         result = 38;
      68            0 :     } else if (muse::RealIsEqual(harmonicValue, 1.8f)) {
      69            0 :         result = 40;
      70              :     }
      71              : 
      72           74 :     return harmonicType == 1 ? result : (result + note->fret());
      73              : }
      74              : 
      75          560 : std::vector<int> standardTuningFor(int midiProgram, int stringsCount)
      76              : {
      77              :     static const std::map<std::pair<int, /* program */ int /* strings count */>, std::vector<int> > tunings {
      78              :         // Guitars 6 strings
      79            0 :         { { 25, 6 }, { 40, 45, 50, 55, 59, 64 } },
      80            0 :         { { 26, 6 }, { 40, 45, 50, 55, 59, 64 } },
      81            0 :         { { 27, 6 }, { 40, 45, 50, 55, 59, 64 } },
      82            0 :         { { 28, 6 }, { 40, 45, 50, 55, 59, 64 } },
      83            0 :         { { 29, 6 }, { 40, 45, 50, 55, 59, 64 } },
      84            0 :         { { 30, 6 }, { 40, 45, 50, 55, 59, 64 } },
      85            0 :         { { 31, 6 }, { 40, 45, 50, 55, 59, 64 } },
      86            0 :         { { 32, 6 }, { 40, 45, 50, 55, 59, 64 } },
      87              :         // Guitars 7 strings
      88            0 :         { { 25, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      89            0 :         { { 26, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      90            0 :         { { 27, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      91            0 :         { { 28, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      92            0 :         { { 29, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      93            0 :         { { 30, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      94            0 :         { { 31, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      95            0 :         { { 32, 7 }, { 35, 40, 45, 50, 55, 59, 64 } },
      96              :         // Basses 4 strings
      97            0 :         { { 33, 4 }, { 28, 33, 38, 43 } },
      98            0 :         { { 34, 4 }, { 28, 33, 38, 43 } },
      99            0 :         { { 35, 4 }, { 28, 33, 38, 43 } },
     100            0 :         { { 36, 4 }, { 28, 33, 38, 43 } },
     101            0 :         { { 37, 4 }, { 28, 33, 38, 43 } },
     102            0 :         { { 38, 4 }, { 28, 33, 38, 43 } },
     103              :         // Basses 5 strings
     104            0 :         { { 33, 5 }, { 23, 28, 33, 38, 43 } },
     105            0 :         { { 34, 5 }, { 23, 28, 33, 38, 43 } },
     106            0 :         { { 35, 5 }, { 23, 28, 33, 38, 43 } },
     107            0 :         { { 36, 5 }, { 23, 28, 33, 38, 43 } },
     108            0 :         { { 37, 5 }, { 23, 28, 33, 38, 43 } },
     109            0 :         { { 38, 5 }, { 23, 28, 33, 38, 43 } },
     110          620 :     };
     111          560 :     std::pair<int, int> key{ midiProgram, stringsCount };
     112              : 
     113          560 :     if (tunings.find(key) == tunings.end()) {
     114           97 :         return tunings.at({ 25, 6 });
     115              :     }
     116          463 :     return tunings.at(key);
     117           29 : }
     118              : 
     119          316 : bool isStandardTuning(int midiProgram, const std::vector<int>& tuning)
     120              : {
     121          316 :     const auto& standardTuning = standardTuningFor(midiProgram, (int)tuning.size());
     122              : 
     123         2094 :     for (size_t i = 0; i < standardTuning.size(); ++i) {
     124         1797 :         if (tuning[i] != standardTuning[i]) {
     125           19 :             return false;
     126              :         }
     127              :     }
     128              : 
     129          297 :     return true;
     130          316 : }
     131              : 
     132          337 : Chord* getLocatedChord(mu::engraving::Score* score, Fraction tickFr, track_idx_t track)
     133              : {
     134          337 :     const Measure* measure = score->tick2measure(tickFr);
     135          337 :     if (!measure) {
     136            0 :         LOGE() << "bend import error: no valid measure for track " << track << ", tick " << tickFr.ticks();
     137            0 :         return nullptr;
     138              :     }
     139              : 
     140          337 :     Chord* chord = measure->findChord(tickFr, track);
     141          337 :     if (!chord) {
     142            0 :         LOGE() << "bend import error: no valid chord for track " << track << ", tick " << tickFr.ticks();
     143            0 :         return nullptr;
     144              :     }
     145              : 
     146          337 :     return chord;
     147              : }
     148              : 
     149            2 : static void addParenthesesToNotes(Chord* ch, const std::vector<Note*>& notes)
     150              : {
     151            4 :     auto createParen = [ch](DirectionH dir) {
     152            4 :         Parenthesis* p = Factory::createParenthesis(ch);
     153            4 :         p->setTrack(ch->track());
     154            4 :         p->setDirection(dir);
     155            4 :         return p;
     156            2 :     };
     157              : 
     158            2 :     NoteParenthesisInfo* parenInfo = new NoteParenthesisInfo(createParen(DirectionH::LEFT), createParen(DirectionH::RIGHT), notes);
     159            2 :     ch->addNoteParenthesisInfo(parenInfo);
     160              : 
     161            4 :     for (Note* n : notes) {
     162            2 :         n->setProperty(Pid::HAS_PARENTHESES, PropertyValue::fromValue(ParenthesesMode::BOTH));
     163            2 :         n->setHideGeneratedParens(true);
     164              :     }
     165            2 : }
     166              : 
     167         2086 : void createGhostNoteParenGroups(Chord* ch)
     168              : {
     169         2086 :     if (!ch->noteParentheses().empty()) {
     170            0 :         return;
     171              :     }
     172              : 
     173         2086 :     const std::vector<Note*>& notes = ch->notes();
     174         2086 :     const size_t count = notes.size();
     175         2086 :     std::vector<Note*> currentGroup;
     176              : 
     177         6912 :     for (size_t i = 0; i <= count; ++i) {
     178         4826 :         if (i < count && notes[i]->ghost()) {
     179            2 :             currentGroup.push_back(notes[i]);
     180         4824 :         } else if (!currentGroup.empty()) {
     181            2 :             addParenthesesToNotes(ch, currentGroup);
     182            2 :             currentGroup.clear();
     183              :         }
     184              :     }
     185         2086 : }
     186              : 
     187          287 : void addPlayCountTexts(Score* score)
     188              : {
     189          287 :     const bool showText = score->style().styleB(Sid::repeatPlayCountShow);
     190          287 :     const bool singleRepeats = score->style().styleB(Sid::repeatPlayCountShowSingleRepeats);
     191         1191 :     for (Measure* m = score->firstMeasure(); m; m = m->nextMeasure()) {
     192          904 :         if (!m->repeatEnd()) {
     193          895 :             continue;
     194              :         }
     195            9 :         const int playCount = m->repeatCount();
     196            9 :         if (!showText || (playCount == 2 && !singleRepeats)) {
     197            5 :             continue;
     198              :         }
     199            4 :         Segment* endBarSeg = m->last(SegmentType::BarLineTypes);
     200            4 :         if (!endBarSeg || endBarSeg->findAnnotation(ElementType::PLAY_COUNT_TEXT, 0, 0)) {
     201            0 :             continue;
     202              :         }
     203            4 :         PlayCountText* pct = Factory::createPlayCountText(endBarSeg);
     204            4 :         pct->setTrack(0);
     205            4 :         score->addElement(pct);
     206              :     }
     207          287 : }
     208              : } // namespace mu::iex::guitarpro
        

Generated by: LCOV version 2.0-1