LCOV - code coverage report
Current view: top level - src/engraving/playback - renderingcontext.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 44 44
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) 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              : #pragma once
      23              : 
      24              : #include "mpe/events.h"
      25              : 
      26              : #include "../dom/chord.h"
      27              : #include "../dom/note.h"
      28              : #include "../dom/sig.h"
      29              : 
      30              : #include "utils/arrangementutils.h"
      31              : #include "utils/pitchutils.h"
      32              : #include "playbackcontext.h"
      33              : 
      34              : namespace mu::engraving {
      35              : struct RenderingContext {
      36              :     muse::mpe::timestamp_t nominalTimestamp = 0;
      37              :     muse::mpe::duration_t nominalDuration = 0;
      38              :     muse::mpe::dynamic_level_t nominalDynamicLevel = 0;
      39              :     int nominalPositionStartTick = 0;
      40              :     int nominalPositionEndTick = 0;
      41              :     int nominalDurationTicks = 0;
      42              :     int positionTickOffset = 0;
      43              : 
      44              :     BeatsPerSecond beatsPerSecond = 0;
      45              :     TimeSigFrac timeSignatureFraction;
      46              : 
      47              :     muse::mpe::ArticulationMap commonArticulations;
      48              : 
      49              :     const Score* score = nullptr;
      50              :     const muse::mpe::ArticulationsProfilePtr profile;
      51              :     const PlaybackContextPtr playbackCtx;
      52              : 
      53         2679 :     bool isValid() const
      54              :     {
      55         2679 :         return score
      56         2679 :                && profile
      57         2679 :                && playbackCtx
      58         5358 :                && beatsPerSecond > 0
      59         2679 :                && nominalDuration > 0
      60         5358 :                && nominalDurationTicks > 0;
      61              :     }
      62              : };
      63              : 
      64         1151 : inline RenderingContext buildRenderingCtx(const Chord* chord, const int tickPositionOffset,
      65              :                                           const muse::mpe::ArticulationsProfilePtr profile, const PlaybackContextPtr playbackCtx,
      66              :                                           const muse::mpe::ArticulationMap& articulations = {})
      67              : {
      68         1151 :     int chordPosTick = chord->tick().ticks();
      69         1151 :     int chordDurationTicks = chord->actualTicks().ticks();
      70         1151 :     int chordPosTickWithOffset = chordPosTick + tickPositionOffset;
      71              : 
      72         1151 :     const Score* score = chord->score();
      73              : 
      74         1151 :     auto chordTnD = timestampAndDurationFromStartAndDurationTicks(score, chordPosTick, chordDurationTicks, tickPositionOffset);
      75              : 
      76         1151 :     BeatsPerSecond bps = score->multipliedTempoAtUtick(chordPosTickWithOffset);
      77         1151 :     TimeSigFrac timeSignatureFraction = score->sigmap()->timesig(chordPosTick).timesig();
      78              : 
      79         1151 :     RenderingContext ctx{ chordTnD.timestamp,
      80         1151 :                           chordTnD.duration,
      81         1151 :                           playbackCtx->appliableDynamicLevel(chord->track(), chordPosTickWithOffset),
      82              :                           chordPosTick,
      83         1151 :                           chordPosTick + chordDurationTicks,
      84              :                           chordDurationTicks,
      85              :                           tickPositionOffset,
      86              :                           bps,
      87              :                           timeSignatureFraction,
      88              :                           articulations,
      89              :                           score,
      90              :                           profile,
      91         2302 :                           playbackCtx };
      92              : 
      93         1151 :     return ctx;
      94              : }
      95              : 
      96              : struct NominalNoteCtx {
      97              :     voice_idx_t voiceIdx = 0;
      98              :     staff_idx_t staffIdx = 0;
      99              :     muse::mpe::timestamp_t timestamp = 0;
     100              :     muse::mpe::duration_t duration = 0;
     101              :     BeatsPerSecond tempo = 0;
     102              :     muse::mpe::dynamic_level_t dynamicLevel = 0;
     103              :     float userVelocityFraction = 0.f;
     104              : 
     105              :     muse::mpe::pitch_level_t pitchLevel = 0;
     106              : 
     107              :     RenderingContext chordCtx;
     108              :     muse::mpe::ArticulationMap articulations;
     109              : 
     110         1558 :     explicit NominalNoteCtx(const Note* note, const RenderingContext& ctx)
     111         1558 :         : voiceIdx(note->voice()),
     112         1558 :         staffIdx(note->staffIdx()),
     113         1558 :         timestamp(ctx.nominalTimestamp),
     114         1558 :         duration(ctx.nominalDuration),
     115         1558 :         tempo(ctx.beatsPerSecond),
     116         1558 :         dynamicLevel(ctx.nominalDynamicLevel),
     117         1558 :         userVelocityFraction(note->userVelocityFraction()),
     118         1558 :         pitchLevel(notePitchLevel(note->playingTpc(),
     119              :                                   note->playingOctave(),
     120              :                                   note->playingTuning())),
     121         1558 :         chordCtx(ctx),
     122         1558 :         articulations(ctx.commonArticulations)
     123              :     {
     124         1558 :     }
     125              : };
     126              : 
     127         1747 : inline muse::mpe::NoteEvent buildNoteEvent(const NominalNoteCtx& ctx, const muse::mpe::PitchCurve& pitchCurve = {})
     128              : {
     129         1747 :     return muse::mpe::NoteEvent(ctx.timestamp,
     130         1747 :                                 ctx.duration,
     131         1747 :                                 static_cast<muse::mpe::voice_layer_idx_t>(ctx.voiceIdx),
     132         1747 :                                 static_cast<muse::mpe::staff_layer_idx_t>(ctx.staffIdx),
     133         1747 :                                 ctx.pitchLevel,
     134         1747 :                                 ctx.dynamicLevel,
     135         1747 :                                 ctx.articulations,
     136         1747 :                                 ctx.tempo.val,
     137         1747 :                                 ctx.userVelocityFraction,
     138         1747 :                                 pitchCurve);
     139              : }
     140              : }
        

Generated by: LCOV version 2.0-1