diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99a3f46ea4139..283796d6beeea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,6 +66,7 @@ option(MUE_BUILD_BRAILLE_TESTS "Build braille tests" ON)
option(MUE_BUILD_CONVERTER_MODULE "Build converter module" ON)
option(MUE_BUILD_ENGRAVING_TESTS "Build engraving tests" ON)
option(MUE_BUILD_ENGRAVING_DEVTOOLS "Build engraving devtools" ON)
+option(MUE_BUILD_ENGRAVING_PLAYBACK "Build engraving playback" ON)
option(MUE_BUILD_IMPORTEXPORT_MODULE "Build importexport module" ON)
option(MUE_BUILD_IMPORTEXPORT_TESTS "Build importexport tests" ON)
option(MUE_BUILD_VIDEOEXPORT_MODULE "Build videoexport module" OFF)
diff --git a/src/engraving/CMakeLists.txt b/src/engraving/CMakeLists.txt
index 7e8b3253abd72..8ef81aa18a84d 100644
--- a/src/engraving/CMakeLists.txt
+++ b/src/engraving/CMakeLists.txt
@@ -49,6 +49,10 @@ if (MUE_BUILD_ENGRAVING_DEVTOOLS)
include(${CMAKE_CURRENT_LIST_DIR}/devtools/devtools.cmake)
endif()
+if (MUE_BUILD_ENGRAVING_PLAYBACK)
+ include(${CMAKE_CURRENT_LIST_DIR}/playback/playback.cmake)
+endif()
+
set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/engravingmodule.cpp
@@ -211,74 +215,7 @@ set(MODULE_SRC
${RENDERING_SCORE_SRC}
${RENDERING_SINGLE_SRC}
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderingcontext.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackcontext.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackcontext.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackmodel.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackmodel.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackeventsrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackeventsrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbacksetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbacksetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/renderbase.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/ornamentsrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/ornamentsrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/glissandosrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/glissandosrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/arpeggiorenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/arpeggiorenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/gracechordsrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/gracechordsrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/tremolorenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/tremolorenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/chordarticulationsrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/chordarticulationsrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/noterenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/noterenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/bendsrenderer.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/renderers/bendsrenderer.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/symbolsmetaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/symbolsmetaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/annotationsmetaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/annotationsmetaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/spannersmetaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/spannersmetaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/tremolometaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/tremolometaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/arpeggiometaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/arpeggiometaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/gracenotesmetaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/gracenotesmetaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/chordlinemetaparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/internal/chordlinemetaparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/notearticulationsparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/notearticulationsparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/chordarticulationsparser.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/chordarticulationsparser.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/metaparsers/metaparserbase.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/setupresolverbase.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/keyboardssetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/keyboardssetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/stringssetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/stringssetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/windssetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/windssetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/percussionssetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/percussionssetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/voicessetupdataresolver.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/mapping/voicessetupdataresolver.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/filterbase.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/chordfilter.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/chordfilter.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/spannerfilter.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/spannerfilter.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/internal/tremolofilter.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/filters/internal/tremolofilter.h
-
- ${CMAKE_CURRENT_LIST_DIR}/playback/utils/pitchutils.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/utils/expressionutils.h
- ${CMAKE_CURRENT_LIST_DIR}/playback/utils/arrangementutils.h
-
+ ${PLAYBACK_SRC}
${DEVTOOLS_SRC}
)
diff --git a/src/engraving/playback/playback.cmake b/src/engraving/playback/playback.cmake
new file mode 100644
index 0000000000000..556be62e11a70
--- /dev/null
+++ b/src/engraving/playback/playback.cmake
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: GPL-3.0-only
+# MuseScore-Studio-CLA-applies
+#
+# MuseScore Studio
+# Music Composition & Notation
+#
+# Copyright (C) 2024 MuseScore Limited
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+set(PLAYBACK_SRC
+ ${CMAKE_CURRENT_LIST_DIR}/renderingcontext.h
+ ${CMAKE_CURRENT_LIST_DIR}/playbackcontext.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playbackcontext.h
+ ${CMAKE_CURRENT_LIST_DIR}/playbackmodel.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playbackmodel.h
+ ${CMAKE_CURRENT_LIST_DIR}/playbackeventsrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playbackeventsrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/playbacksetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playbacksetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/renderbase.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/ornamentsrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/ornamentsrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/glissandosrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/glissandosrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/arpeggiorenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/arpeggiorenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/gracechordsrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/gracechordsrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/tremolorenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/tremolorenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/chordarticulationsrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/chordarticulationsrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/noterenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/noterenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/bendsrenderer.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/renderers/bendsrenderer.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/symbolsmetaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/symbolsmetaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/annotationsmetaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/annotationsmetaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/spannersmetaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/spannersmetaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/tremolometaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/tremolometaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/arpeggiometaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/arpeggiometaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/gracenotesmetaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/gracenotesmetaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/chordlinemetaparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/internal/chordlinemetaparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/notearticulationsparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/notearticulationsparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/chordarticulationsparser.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/chordarticulationsparser.h
+ ${CMAKE_CURRENT_LIST_DIR}/metaparsers/metaparserbase.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/setupresolverbase.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/keyboardssetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/keyboardssetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/stringssetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/stringssetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/windssetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/windssetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/percussionssetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/percussionssetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/voicessetupdataresolver.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/mapping/voicessetupdataresolver.h
+ ${CMAKE_CURRENT_LIST_DIR}/filters/filterbase.h
+ ${CMAKE_CURRENT_LIST_DIR}/filters/chordfilter.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/filters/chordfilter.h
+ ${CMAKE_CURRENT_LIST_DIR}/filters/spannerfilter.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/filters/spannerfilter.h
+ ${CMAKE_CURRENT_LIST_DIR}/filters/internal/tremolofilter.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/filters/internal/tremolofilter.h
+
+ ${CMAKE_CURRENT_LIST_DIR}/utils/pitchutils.h
+ ${CMAKE_CURRENT_LIST_DIR}/utils/expressionutils.h
+ ${CMAKE_CURRENT_LIST_DIR}/utils/arrangementutils.h
+)
diff --git a/src/engraving/tests/CMakeLists.txt b/src/engraving/tests/CMakeLists.txt
index 907c82d580320..c4845897441ac 100644
--- a/src/engraving/tests/CMakeLists.txt
+++ b/src/engraving/tests/CMakeLists.txt
@@ -67,10 +67,6 @@ set(MODULE_TEST_SRC
${CMAKE_CURRENT_LIST_DIR}/note_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/parts_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/pitchwheelrender_tests.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackeventsrendering_tests.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackmodel_tests.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/playbackcontext_tests.cpp
- ${CMAKE_CURRENT_LIST_DIR}/playback/bendsrenderer_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/readwriteundoreset_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/remove_tests.cpp
${CMAKE_CURRENT_LIST_DIR}/repeat_tests.cpp
@@ -103,6 +99,15 @@ set(MODULE_TEST_SRC ${MODULE_TEST_SRC}
)
endif()
+if(MUE_BUILD_ENGRAVING_PLAYBACK)
+set(MODULE_TEST_SRC ${MODULE_TEST_SRC}
+ ${CMAKE_CURRENT_LIST_DIR}/playback/playbackeventsrendering_tests.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playback/playbackmodel_tests.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playback/playbackcontext_tests.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/playback/bendsrenderer_tests.cpp
+)
+endif()
+
set(MODULE_TEST_LINK
engraving
)
diff --git a/src/notation/CMakeLists.txt b/src/notation/CMakeLists.txt
index cacaabfaaf781..88097a34b9336 100644
--- a/src/notation/CMakeLists.txt
+++ b/src/notation/CMakeLists.txt
@@ -26,6 +26,19 @@ set(MODULE_QML_IMPORT ${CMAKE_CURRENT_LIST_DIR}/qml)
include(${CMAKE_CURRENT_LIST_DIR}/view/widgets/widgets.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/view/styledialog/styledialog.cmake)
+if (MUE_BUILD_ENGRAVING_PLAYBACK)
+ set(NOTATION_PLAYBACK_SRC_FILES
+ ${CMAKE_CURRENT_LIST_DIR}/internal/notationplayback.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/internal/notationplayback.h
+ )
+ set(MODULE_DEF ${MODULE_DEF} -DMUE_BUILD_ENGRAVING_PLAYBACK)
+else()
+ set(NOTATION_PLAYBACK_SRC_FILES
+ ${CMAKE_CURRENT_LIST_DIR}/internal/notationplaybackstub.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/internal/notationplaybackstub.h
+ )
+endif()
+
set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/notationmodule.cpp
${CMAKE_CURRENT_LIST_DIR}/notationmodule.h
@@ -92,8 +105,7 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/positionswriter.h
${CMAKE_CURRENT_LIST_DIR}/internal/mscnotationwriter.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/mscnotationwriter.h
- ${CMAKE_CURRENT_LIST_DIR}/internal/notationplayback.cpp
- ${CMAKE_CURRENT_LIST_DIR}/internal/notationplayback.h
+ ${NOTATION_PLAYBACK_SRC_FILES}
${CMAKE_CURRENT_LIST_DIR}/internal/midiinputoutputcontroller.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/midiinputoutputcontroller.h
${CMAKE_CURRENT_LIST_DIR}/internal/notationmidiinput.cpp
diff --git a/src/notation/internal/masternotation.cpp b/src/notation/internal/masternotation.cpp
index b661d3b2764fd..8a9ec141e9033 100644
--- a/src/notation/internal/masternotation.cpp
+++ b/src/notation/internal/masternotation.cpp
@@ -39,12 +39,19 @@
#include "engraving/dom/box.h"
#include "engraving/dom/keysig.h"
#include "engraving/dom/rest.h"
+#include "engraving/dom/sig.h"
#include "engraving/dom/tempotext.h"
#include "engraving/dom/undo.h"
#include "excerptnotation.h"
#include "masternotationparts.h"
+
+#ifdef MUE_BUILD_ENGRAVING_PLAYBACK
#include "notationplayback.h"
+#else
+#include "notationplaybackstub.h"
+#endif
+
#include "../notationerrors.h"
using namespace mu::notation;
@@ -69,7 +76,12 @@ MasterNotation::MasterNotation(const muse::modularity::ContextPtr& iocCtx)
: Notation(iocCtx)
{
m_parts = std::make_shared(this, interaction(), undoStack());
+
+#ifdef MUE_BUILD_ENGRAVING_PLAYBACK
m_notationPlayback = std::make_shared(this, m_notationChanged, iocCtx);
+#else
+ m_notationPlayback = std::make_shared();
+#endif
m_parts->partsChanged().onNotify(this, [this]() {
notifyAboutNotationChanged();
diff --git a/src/notation/internal/notation.cpp b/src/notation/internal/notation.cpp
index c026144882eed..4c6b4863c7105 100644
--- a/src/notation/internal/notation.cpp
+++ b/src/notation/internal/notation.cpp
@@ -30,7 +30,6 @@
#include "notationviewstate.h"
#include "notationsolomutestate.h"
#include "notationinteraction.h"
-#include "notationplayback.h"
#include "notationundostack.h"
#include "notationstyle.h"
#include "notationelements.h"
diff --git a/src/notation/internal/notationplaybackstub.cpp b/src/notation/internal/notationplaybackstub.cpp
new file mode 100644
index 0000000000000..283ea6c396f68
--- /dev/null
+++ b/src/notation/internal/notationplaybackstub.cpp
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-only
+ * MuseScore-Studio-CLA-applies
+ *
+ * MuseScore Studio
+ * Music Composition & Notation
+ *
+ * Copyright (C) 2024 MuseScore Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include "notationplaybackstub.h"
+
+using namespace mu;
+using namespace mu::notation;
+using namespace mu::engraving;
+using namespace muse;
+using namespace muse::midi;
+using namespace muse::async;
+
+NotationPlaybackStub::NotationPlaybackStub()
+{
+}
+
+void NotationPlaybackStub::init()
+{
+}
+
+const engraving::InstrumentTrackId& NotationPlaybackStub::metronomeTrackId() const
+{
+ static const engraving::InstrumentTrackId dummy;
+ return dummy;
+}
+
+engraving::InstrumentTrackId NotationPlaybackStub::chordSymbolsTrackId(const ID&) const
+{
+ static const engraving::InstrumentTrackId dummy;
+ return dummy;
+}
+
+bool NotationPlaybackStub::isChordSymbolsTrack(const engraving::InstrumentTrackId&) const
+{
+ return false;
+}
+
+const muse::mpe::PlaybackData& NotationPlaybackStub::trackPlaybackData(const engraving::InstrumentTrackId&) const
+{
+ static const muse::mpe::PlaybackData dummy;
+ return dummy;
+}
+
+void NotationPlaybackStub::triggerEventsForItems(const std::vector&)
+{
+}
+
+void NotationPlaybackStub::triggerMetronome(int)
+{
+}
+
+InstrumentTrackIdSet NotationPlaybackStub::existingTrackIdSet() const
+{
+ return engraving::InstrumentTrackIdSet();
+}
+
+muse::async::Channel NotationPlaybackStub::trackAdded() const
+{
+ return muse::async::Channel();
+}
+
+muse::async::Channel NotationPlaybackStub::trackRemoved() const
+{
+ return muse::async::Channel();
+}
+
+muse::audio::secs_t NotationPlaybackStub::totalPlayTime() const
+{
+ return muse::audio::secs_t();
+}
+
+muse::async::Channel NotationPlaybackStub::totalPlayTimeChanged() const
+{
+ return muse::async::Channel();
+}
+
+muse::audio::secs_t NotationPlaybackStub::playedTickToSec(tick_t) const
+{
+ return muse::audio::secs_t();
+}
+
+tick_t NotationPlaybackStub::secToPlayedTick(muse::audio::secs_t) const
+{
+ return 0;
+}
+
+tick_t NotationPlaybackStub::secToTick(muse::audio::secs_t) const
+{
+ return 0;
+}
+
+RetVal NotationPlaybackStub::playPositionTickByRawTick(muse::midi::tick_t) const
+{
+ return RetVal::make_ok(0);
+}
+
+RetVal NotationPlaybackStub::playPositionTickByElement(const EngravingItem*) const
+{
+ return RetVal::make_ok(0);
+}
+
+void NotationPlaybackStub::addLoopBoundary(LoopBoundaryType, tick_t)
+{
+}
+
+void NotationPlaybackStub::setLoopBoundariesEnabled(bool)
+{
+}
+
+const LoopBoundaries& NotationPlaybackStub::loopBoundaries() const
+{
+ static const LoopBoundaries dummy;
+ return dummy;
+}
+
+Notification NotationPlaybackStub::loopBoundariesChanged() const
+{
+ return Notification();
+}
+
+const Tempo& NotationPlaybackStub::tempo(tick_t) const
+{
+ static const Tempo dummy;
+ return dummy;
+}
+
+MeasureBeat NotationPlaybackStub::beat(tick_t) const
+{
+ return MeasureBeat();
+}
+
+tick_t NotationPlaybackStub::beatToRawTick(int, int) const
+{
+ return 0;
+}
+
+double NotationPlaybackStub::tempoMultiplier() const
+{
+ return 0;
+}
+
+void NotationPlaybackStub::setTempoMultiplier(double)
+{
+}
+
+void NotationPlaybackStub::addSoundFlags(const std::vector&)
+{
+}
+
+void NotationPlaybackStub::removeSoundFlags(const InstrumentTrackIdSet&)
+{
+}
+
+bool NotationPlaybackStub::hasSoundFlags(const engraving::InstrumentTrackIdSet&)
+{
+ return false;
+}
diff --git a/src/notation/internal/notationplaybackstub.h b/src/notation/internal/notationplaybackstub.h
new file mode 100644
index 0000000000000..ab21e87b4a146
--- /dev/null
+++ b/src/notation/internal/notationplaybackstub.h
@@ -0,0 +1,72 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-only
+ * MuseScore-Studio-CLA-applies
+ *
+ * MuseScore Studio
+ * Music Composition & Notation
+ *
+ * Copyright (C) 2024 MuseScore Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "../inotationplayback.h"
+
+namespace mu::notation {
+class NotationPlaybackStub : public INotationPlayback
+{
+public:
+ NotationPlaybackStub();
+
+ void init() override;
+
+ const engraving::InstrumentTrackId& metronomeTrackId() const override;
+ engraving::InstrumentTrackId chordSymbolsTrackId(const muse::ID& partId) const override;
+ bool isChordSymbolsTrack(const engraving::InstrumentTrackId& trackId) const override;
+
+ const muse::mpe::PlaybackData& trackPlaybackData(const engraving::InstrumentTrackId& trackId) const override;
+ void triggerEventsForItems(const std::vector& items) override;
+ void triggerMetronome(int tick) override;
+
+ engraving::InstrumentTrackIdSet existingTrackIdSet() const override;
+ muse::async::Channel trackAdded() const override;
+ muse::async::Channel trackRemoved() const override;
+
+ muse::audio::secs_t totalPlayTime() const override;
+ muse::async::Channel totalPlayTimeChanged() const override;
+
+ muse::audio::secs_t playedTickToSec(muse::midi::tick_t tick) const override;
+ muse::midi::tick_t secToPlayedTick(muse::audio::secs_t sec) const override;
+ muse::midi::tick_t secToTick(muse::audio::secs_t sec) const override;
+
+ muse::RetVal playPositionTickByRawTick(muse::midi::tick_t tick) const override;
+ muse::RetVal playPositionTickByElement(const EngravingItem* element) const override;
+
+ void addLoopBoundary(LoopBoundaryType boundaryType, muse::midi::tick_t tick) override;
+ void setLoopBoundariesEnabled(bool enabled) override;
+ const LoopBoundaries& loopBoundaries() const override;
+ muse::async::Notification loopBoundariesChanged() const override;
+
+ const Tempo& tempo(muse::midi::tick_t tick) const override;
+ MeasureBeat beat(muse::midi::tick_t tick) const override;
+ muse::midi::tick_t beatToRawTick(int measureIndex, int beatIndex) const override;
+
+ double tempoMultiplier() const override;
+ void setTempoMultiplier(double multiplier) override;
+
+ void addSoundFlags(const std::vector& staffTextList) override;
+ void removeSoundFlags(const engraving::InstrumentTrackIdSet& trackIdSet) override;
+ bool hasSoundFlags(const engraving::InstrumentTrackIdSet& trackIdSet) override;
+};
+}