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) 2024 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 "drumsetloader.h"
24 :
25 : #include "notation/inotationparts.h"
26 : #include "notation/notationtypes.h"
27 : #include "notationscene/utilities/percussionutilities.h"
28 :
29 : #include "global/types/bytearray.h"
30 :
31 : using namespace mu::playback;
32 : using namespace muse::audio;
33 : using namespace mu::notation;
34 : using namespace mu::engraving;
35 :
36 0 : void DrumsetLoader::loadDrumset(INotationPtr notation, const InstrumentTrackId& trackId, const AudioResourceMeta& resourceMeta)
37 : {
38 0 : TRACEFUNC;
39 :
40 0 : if (!notation) {
41 0 : return;
42 : }
43 :
44 : // restore the default drumset when changing from MuseSounds to MS Basic / VST
45 0 : if (!isResourceType(resourceMeta, AudioResourceType::MuseSamplerSoundPack)) {
46 0 : const InstrumentTemplate& templ = instrumentsRepository()->instrumentTemplate(trackId.instrumentId);
47 0 : if (!templ.useDrumset) {
48 0 : return;
49 : }
50 :
51 0 : if (templ.drumset) {
52 0 : replaceDrumset(notation, trackId, *templ.drumset);
53 0 : } else if (mu::engraving::smDrumset) {
54 0 : replaceDrumset(notation, trackId, *mu::engraving::smDrumset);
55 : }
56 :
57 0 : return;
58 : }
59 :
60 0 : int instrumentId = muse::audio::intAttribute(resourceMeta, u"museUID");
61 :
62 0 : auto it = m_drumsetCache.find(instrumentId);
63 0 : if (it != m_drumsetCache.end()) {
64 0 : if (it->second == std::nullopt) {
65 0 : return; // drumset mapping not available
66 : }
67 :
68 0 : replaceDrumset(notation, trackId, it->second.value());
69 0 : return;
70 : }
71 :
72 0 : muse::ByteArray drumMapping = museSampler()->drumMapping(instrumentId);
73 0 : if (drumMapping.empty()) {
74 0 : m_drumsetCache.emplace(instrumentId, std::nullopt);
75 0 : return;
76 : }
77 :
78 0 : Drumset drumset;
79 0 : PercussionUtilities::readDrumset(drumMapping, drumset);
80 0 : replaceDrumset(notation, trackId, drumset);
81 :
82 0 : m_drumsetCache.emplace(instrumentId, std::move(drumset));
83 0 : }
84 :
85 0 : void DrumsetLoader::replaceDrumset(INotationPtr notation, const InstrumentTrackId& trackId, const Drumset& drumset)
86 : {
87 0 : INotationPartsPtr parts = notation->parts();
88 0 : const Part* part = parts->part(trackId.partId);
89 0 : if (!part) {
90 0 : return;
91 : }
92 :
93 0 : QString instrumentId = trackId.instrumentId.toQString();
94 0 : const mu::engraving::InstrumentList& instruments = part->instruments();
95 :
96 0 : for (auto it = instruments.cbegin(); it != instruments.cend(); ++it) {
97 0 : if (it->second->id() != trackId.instrumentId) {
98 0 : continue;
99 : }
100 :
101 0 : InstrumentKey instrumentKey;
102 0 : instrumentKey.instrumentId = instrumentId;
103 0 : instrumentKey.partId = trackId.partId;
104 0 : instrumentKey.tick = Fraction::fromTicks(it->first);
105 :
106 0 : parts->replaceDrumset(instrumentKey, drumset, false /*undoable*/);
107 0 : }
108 0 : }
|