LCOV - code coverage report
Current view: top level - src/engraving/playback - playbackmodel.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 2 2
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              : 
      23              : #pragma once
      24              : 
      25              : #include <unordered_map>
      26              : #include <map>
      27              : #include <functional>
      28              : 
      29              : #include "async/asyncable.h"
      30              : #include "async/channel.h"
      31              : #include "async/notification.h"
      32              : #include "types/id.h"
      33              : #include "modularity/ioc.h"
      34              : #include "mpe/events.h"
      35              : #include "mpe/iarticulationprofilesrepository.h"
      36              : 
      37              : #include "../types/types.h"
      38              : #include "playbackeventsrenderer.h"
      39              : #include "playbacksetupdataresolver.h"
      40              : #include "playbackcontext.h"
      41              : 
      42              : namespace mu::engraving {
      43              : class Score;
      44              : class Note;
      45              : class EngravingItem;
      46              : class Segment;
      47              : class Instrument;
      48              : class RepeatList;
      49              : 
      50              : class PlaybackModel : public muse::Contextable, public muse::async::Asyncable
      51              : {
      52              : public:
      53              :     muse::GlobalInject<muse::mpe::IArticulationProfilesRepository> profilesRepository;
      54              : 
      55              : public:
      56           23 :     PlaybackModel(const muse::modularity::ContextPtr& iocCtx)
      57           23 :         : muse::Contextable(iocCtx) {}
      58              : 
      59              :     void load(Score* score);
      60              :     void reload();
      61              : 
      62              :     void setSendEventsOnScoreChange(const InstrumentTrackId& trackId, bool send);
      63              :     void sendEventsForChangedTracks();
      64              : 
      65              :     muse::async::Channel<InstrumentTrackIdSet> tracksDataChanged() const;
      66              : 
      67              :     bool isPlayRepeatsEnabled() const;
      68              :     void setPlayRepeats(const bool isEnabled);
      69              : 
      70              :     bool isPlayChordSymbolsEnabled() const;
      71              :     void setPlayChordSymbols(const bool isEnabled);
      72              : 
      73              :     bool useScoreDynamicsForOffstreamPlayback() const;
      74              :     void setUseScoreDynamicsForOffstreamPlayback(bool use);
      75              : 
      76              :     bool isMetronomeEnabled() const;
      77              :     void setIsMetronomeEnabled(const bool isEnabled);
      78              : 
      79              :     const InstrumentTrackId& metronomeTrackId() const;
      80              :     InstrumentTrackId chordSymbolsTrackId(const ID& partId) const;
      81              :     bool isChordSymbolsTrack(const InstrumentTrackId& trackId) const;
      82              : 
      83              :     bool hasSoundFlags(const InstrumentTrackId& trackId) const;
      84              : 
      85              :     muse::mpe::PlaybackData& resolveTrackPlaybackData(const InstrumentTrackId& trackId);
      86              :     muse::mpe::PlaybackData& resolveTrackPlaybackData(const ID& partId, const String& instrumentId);
      87              : 
      88              :     void triggerEventsForItems(const std::vector<const EngravingItem*>& items, muse::mpe::duration_t duration, bool flushSound);
      89              :     void triggerMetronome(int tick);
      90              :     void triggerCountIn(int tick, muse::mpe::duration_t& countInDuration);
      91              : 
      92              :     InstrumentTrackIdSet existingTrackIdSet() const;
      93              :     muse::async::Channel<InstrumentTrackId> trackAdded() const;
      94              :     muse::async::Channel<InstrumentTrackId> trackRemoved() const;
      95              : 
      96              : private:
      97              :     static const InstrumentTrackId METRONOME_TRACK_ID;
      98              :     static const InstrumentTrackId CHORD_SYMBOLS_TRACK_ID;
      99              : 
     100              :     using ChangedTrackIdSet = InstrumentTrackIdSet;
     101              : 
     102              :     struct TickBoundaries
     103              :     {
     104              :         int tickFrom = -1;
     105              :         int tickTo = -1;
     106              :     };
     107              : 
     108              :     struct TrackBoundaries
     109              :     {
     110              :         track_idx_t trackFrom = muse::nidx;
     111              :         track_idx_t trackTo = muse::nidx;
     112              :     };
     113              : 
     114              :     struct PartData
     115              :     {
     116              :         muse::mpe::DynamicAutomationLayers dynamics;
     117              :         std::map<muse::mpe::timestamp_t, muse::mpe::SoundPresetChangeEventList> soundPresets;
     118              :         std::map<muse::mpe::timestamp_t, muse::mpe::TextArticulationEventList> textArticulations;
     119              :         std::map<muse::mpe::timestamp_t, muse::mpe::SyllableEventList> syllables;
     120              :     };
     121              : 
     122              :     InstrumentTrackId idKey(const EngravingItem* item) const;
     123              :     InstrumentTrackId idKey(const std::vector<const EngravingItem*>& items) const;
     124              :     InstrumentTrackId idKey(const ID& partId, const String& instrumentId) const;
     125              : 
     126              :     void update(const int tickFrom, const int tickTo, const track_idx_t trackFrom, const track_idx_t trackTo,
     127              :                 ChangedTrackIdSet* trackChanges = nullptr);
     128              :     void updateSetupData();
     129              :     void updateContext(const track_idx_t trackFrom, const track_idx_t trackTo, const int tickFrom, const int tickTo);
     130              :     void applyContextToTrackData(const InstrumentTrackId& trackId, const PartData& data);
     131              :     void updateEvents(const int tickFrom, const int tickTo, const track_idx_t trackFrom, const track_idx_t trackTo,
     132              :                       ChangedTrackIdSet* trackChanges = nullptr);
     133              : 
     134              :     void reloadMetronomeEvents();
     135              : 
     136              :     void processSegment(const int tickPositionOffset, const Segment* segment, const std::set<staff_idx_t>& staffIdxSet,
     137              :                         bool isFirstChordRestSegmentOfMeasure, ChangedTrackIdSet* trackChanges);
     138              :     void processMeasureRepeat(const int tickPositionOffset, const MeasureRepeat* measureRepeat, const Measure* currentMeasure,
     139              :                               const staff_idx_t staffIdx, ChangedTrackIdSet* trackChanges);
     140              : 
     141              :     bool hasToReloadTracks(const ScoreChanges& changes) const;
     142              :     bool hasToReloadScore(const ScoreChanges& changes) const;
     143              :     bool hasAutomationChange(const ScoreChanges& changes) const;
     144              : 
     145              :     void clearExpiredTracks();
     146              :     void clearExpiredEvents(const int tickFrom, const int tickTo, const track_idx_t trackFrom, const track_idx_t trackTo,
     147              :                             ChangedTrackIdSet* trackChanges = nullptr);
     148              :     void collectChangesTracks(const InstrumentTrackId& trackId, ChangedTrackIdSet* result);
     149              :     void notifyAboutChanges(const InstrumentTrackIdSet& oldTracks, const InstrumentTrackIdSet& changedTracks);
     150              : 
     151              :     void sendEvents(const InstrumentTrackId& trackId);
     152              : 
     153              :     void removeEventsFromRange(const track_idx_t trackFrom, const track_idx_t trackTo, const muse::mpe::timestamp_t timestampFrom = -1,
     154              :                                const muse::mpe::timestamp_t timestampTo = -1, ChangedTrackIdSet* trackChanges = nullptr);
     155              :     void removeTrackEvents(const InstrumentTrackId& trackId, const muse::mpe::timestamp_t timestampFrom = -1,
     156              :                            const muse::mpe::timestamp_t timestampTo = -1, ChangedTrackIdSet* trackChanges = nullptr);
     157              : 
     158              :     bool shouldSkipChanges(const ScoreChanges& changes) const;
     159              : 
     160              :     TrackBoundaries trackBoundaries(const ScoreChanges& changes) const;
     161              :     TickBoundaries tickBoundaries(const ScoreChanges& changes) const;
     162              : 
     163              :     const RepeatList& repeatList() const;
     164              : 
     165              :     muse::mpe::ArticulationsProfilePtr defaultActiculationProfile(const InstrumentTrackId& trackId) const;
     166              : 
     167              :     static void applyTiedNotesTickBoundaries(const Note* note, TickBoundaries& tickBoundaries);
     168              :     static void applyTieTickBoundaries(const Tie* tie, TickBoundaries& tickBoundaries);
     169              : 
     170              :     Score* m_score = nullptr;
     171              :     bool m_expandRepeats = true;
     172              :     bool m_playChordSymbols = true;
     173              :     bool m_useScoreDynamicsForOffstreamPlayback = true;
     174              :     bool m_metronomeEnabled = true;
     175              : 
     176              :     PlaybackEventsRenderer m_renderer;
     177              :     PlaybackSetupDataResolver m_setupResolver;
     178              : 
     179              :     PlaybackContextPtr m_playbackCtx;
     180              :     std::unordered_map<InstrumentTrackId, muse::mpe::PlaybackData> m_playbackDataMap;
     181              :     std::unordered_map<InstrumentTrackId, bool> m_sendEventsOnScoreChangeMap;
     182              : 
     183              :     InstrumentTrackIdSet m_changedTrackIdSet;
     184              : 
     185              :     muse::async::Channel<InstrumentTrackIdSet> m_tracksDataChanged;
     186              :     muse::async::Channel<InstrumentTrackId> m_trackAdded;
     187              :     muse::async::Channel<InstrumentTrackId> m_trackRemoved;
     188              : };
     189              : }
        

Generated by: LCOV version 2.0-1