LCOV - code coverage report
Current view: top level - src/engraving/playback/renderers - glissandosrenderer.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 93.2 % 44 41
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              : #include "glissandosrenderer.h"
      24              : 
      25              : #include "dom/glissando.h"
      26              : 
      27              : #include "playback/renderingcontext.h"
      28              : #include "playback/utils/expressionutils.h"
      29              : 
      30              : using namespace mu::engraving;
      31              : using namespace muse;
      32              : using namespace muse::mpe;
      33              : 
      34            5 : static std::vector<int> pitchSteps(const Note* note)
      35              : {
      36            5 :     const Glissando* glissando = nullptr;
      37            5 :     for (const Spanner* spanner : note->spannerFor()) {
      38            5 :         if (spanner->isGlissando()) {
      39            5 :             glissando = toGlissando(spanner);
      40            5 :             break;
      41              :         }
      42              :     }
      43              : 
      44            5 :     if (!glissando) {
      45            0 :         return {};
      46              :     }
      47              : 
      48            5 :     std::vector<int> pitchSteps;
      49            5 :     Glissando::pitchSteps(glissando, pitchSteps);
      50              : 
      51            5 :     return pitchSteps;
      52            5 : }
      53              : 
      54            1 : muse::mpe::duration_t GlissandosRenderer::discreteGlissandoStepDuration(const Note* note, const duration_t noteDuration)
      55              : {
      56            1 :     const std::vector<int> steps = pitchSteps(note);
      57            1 :     if (steps.empty()) {
      58            0 :         return 0;
      59              :     }
      60              : 
      61            1 :     return noteDuration / static_cast<float>(steps.size());
      62            1 : }
      63              : 
      64            4 : void GlissandosRenderer::renderDiscreteGlissando(const Note* note, NominalNoteCtx& ctx, mpe::PlaybackEventList& result)
      65              : {
      66            4 :     const std::vector<int> steps = pitchSteps(note);
      67            4 :     if (steps.empty()) {
      68            0 :         return;
      69              :     }
      70              : 
      71            4 :     const size_t stepsCount = steps.size();
      72            4 :     const float durationStep = ctx.duration / static_cast<float>(stepsCount);
      73            4 :     size_t firstStep = 0;
      74              : 
      75            4 :     if (note->tieBack()) {
      76            1 :         mpe::ArticulationMeta& meta = ctx.articulations.at(ArticulationType::DiscreteGlissando).meta;
      77            1 :         meta.timestamp += durationStep;
      78            1 :         meta.overallDuration -= durationStep;
      79            1 :         firstStep = 1;
      80              :     }
      81              : 
      82           25 :     for (size_t i = firstStep; i < stepsCount; ++i) {
      83           21 :         NominalNoteCtx noteCtx(ctx);
      84           21 :         noteCtx.duration = durationStep;
      85           21 :         noteCtx.timestamp += i * durationStep;
      86           21 :         noteCtx.pitchLevel += steps.at(i) * mpe::PITCH_LEVEL_STEP;
      87              : 
      88           21 :         const int utick = timestampToTick(noteCtx.chordCtx.score, noteCtx.timestamp);
      89           21 :         noteCtx.dynamicLevel = ctx.chordCtx.playbackCtx->appliableDynamicLevel(note->track(), utick);
      90              : 
      91           21 :         updateArticulationBoundaries(ArticulationType::DiscreteGlissando,
      92              :                                      noteCtx.timestamp,
      93              :                                      noteCtx.duration,
      94              :                                      noteCtx.articulations);
      95              : 
      96           21 :         result.emplace_back(buildNoteEvent(noteCtx));
      97           21 :     }
      98           25 : }
      99              : 
     100            3 : void GlissandosRenderer::renderContinuousGlissando(const Note*, NominalNoteCtx& ctx, muse::mpe::PlaybackEventList& result)
     101              : {
     102            3 :     result.emplace_back(buildNoteEvent(ctx));
     103            6 : }
        

Generated by: LCOV version 2.0-1