LCOV - code coverage report
Current view: top level - src/engraving/compat/midi - pausemap.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 92.3 % 26 24
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              : 
      23              : /**
      24              :  \file
      25              :  Implementation of class PauseMap.
      26              : */
      27              : 
      28              : #include "pausemap.h"
      29              : 
      30              : #include "dom/repeatlist.h"
      31              : #include "dom/score.h"
      32              : #include "dom/sig.h"
      33              : #include "dom/tempotimeline.h"
      34              : 
      35              : #include "log.h"
      36              : 
      37              : using namespace mu;
      38              : using namespace muse;
      39              : 
      40              : namespace mu::engraving {
      41              : //---------------------------------------------------------
      42              : //   calculate
      43              : //    MIDI files cannot contain pauses so insert extra ticks and tempo changes instead.
      44              : //    The PauseMap and tempo events are fully unwound to account for pauses on repeats.
      45              : //---------------------------------------------------------
      46              : 
      47           13 : void PauseMap::calculate(const Score* s)
      48              : {
      49           13 :     IF_ASSERT_FAILED(s) {
      50            0 :         LOGE() << "failed to calculate pause map";
      51              :     }
      52              : 
      53           13 :     insert(std::pair<const int, int>(0, 0));    // can't start with a pause
      54              : 
      55           13 :     const TimeSigMap* sigmap = s->sigmap();
      56           13 :     const RepeatList& repeatList = s->repeatList();
      57              : 
      58           35 :     for (const TempoTimePoint& point : s->tempoTimeline().points()) {
      59           22 :         const int utick = point.utick;
      60              : 
      61           22 :         if (point.pause <= 0.0) {
      62              :             // We have a regular tempo change.
      63           21 :             m_tempoEvents[tickWithPauses(utick)] = point.bps;
      64           21 :             continue;
      65              :         }
      66              : 
      67              :         // We have a pause event.
      68            1 :         const int tick = repeatList.utick2tick(utick);
      69            1 :         Fraction timeSig(sigmap->timesig(tick).timesig());
      70            1 :         double quarterNotesPerMeasure = (4.0 * timeSig.numerator()) / timeSig.denominator();
      71            1 :         int ticksPerMeasure =  quarterNotesPerMeasure * Constants::DIVISION;           // store a full measure of ticks to keep barlines in same places
      72            1 :         m_tempoEvents[tickWithPauses(utick)] = quarterNotesPerMeasure / point.pause;           // new tempo for pause
      73            1 :         insert(std::pair<const int, int>(utick, ticksPerMeasure + offsetAtUTick(utick)));            // store running total of extra ticks
      74            1 :         m_tempoEvents[tickWithPauses(utick)] = point.bps;           // restore previous tempo
      75              :     }
      76           13 : }
      77              : 
      78              : //---------------------------------------------------------
      79              : //   offsetAtUTick
      80              : //    In total, how many extra ticks have been inserted prior to this utick.
      81              : //---------------------------------------------------------
      82              : 
      83          567 : int PauseMap::offsetAtUTick(int utick) const
      84              : {
      85              :     // make sure calculate was called
      86          567 :     IF_ASSERT_FAILED(!empty()) {
      87            0 :         LOGE() << "accessing empty container";
      88              :     }
      89              : 
      90          567 :     auto i = upper_bound(utick);
      91          567 :     if (i != begin()) {
      92          567 :         --i;
      93              :     }
      94         1134 :     return i->second;
      95              : }
      96              : }
        

Generated by: LCOV version 2.0-1