Skip to content

Commit

Permalink
Percussion panel - fix layout reset for Muse Sampler drumsets
Browse files Browse the repository at this point in the history
  • Loading branch information
mathesoncalum committed Feb 14, 2025
1 parent b9ce664 commit 07b47b9
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 33 deletions.
17 changes: 17 additions & 0 deletions src/notation/utilities/percussionutilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@
using namespace mu::notation;
using namespace mu::engraving;

void PercussionUtilities::readDrumset(const muse::ByteArray& drumMapping, Drumset& drumset)
{
XmlReader reader(drumMapping);

while (reader.readNextStartElement()) {
if (reader.name() == "museScore") {
while (reader.readNextStartElement()) {
if (reader.name() == "Drum") {
drumset.load(reader);
} else {
reader.unknown();
}
}
}
}
}

/// Returns a drum note prepared for preview.
std::shared_ptr<Chord> PercussionUtilities::getDrumNoteForPreview(const Drumset* drumset, int pitch)
{
Expand Down
2 changes: 2 additions & 0 deletions src/notation/utilities/percussionutilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "iinteractive.h"

#include "engraving/rendering/isinglerenderer.h"
#include "engraving/rw/xmlreader.h"

#include "engraving/dom/chord.h"
#include "engraving/dom/drumset.h"
Expand All @@ -45,6 +46,7 @@ class PercussionUtilities
INJECT_STATIC(mu::engraving::rendering::ISingleRenderer, engravingRender)

public:
static void readDrumset(const muse::ByteArray& drumMapping, mu::engraving::Drumset& drumset);
static std::shared_ptr<mu::engraving::Chord> getDrumNoteForPreview(const mu::engraving::Drumset* drumset, int pitch);
static void editPercussionShortcut(mu::engraving::Drumset& drumset, int originPitch);

Expand Down
49 changes: 43 additions & 6 deletions src/notation/view/percussionpanel/percussionpanelmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,16 +490,14 @@ void PercussionPanelModel::resetLayout()
Instrument* inst = instAndPart.first;
Part* part = instAndPart.second;

IF_ASSERT_FAILED(inst && inst->drumset() && part) {
IF_ASSERT_FAILED(audioSettings() && inst && part) {
return;
}

const InstrumentTemplate& instTemplate = instrumentsRepository()->instrumentTemplate(inst->id());
const Drumset* defaultDrumset = instTemplate.drumset;
const muse::audio::AudioResourceMeta& resourceMeta = audioSettings()->trackInputParams(currentTrackId()).resourceMeta;
const bool isMuseSamplerDrumset = resourceMeta.type == muse::audio::AudioResourceType::MuseSamplerSoundPack;

IF_ASSERT_FAILED(defaultDrumset) {
return;
}
Drumset defaultDrumset = isMuseSamplerDrumset ? museSamplerDefaultDrumset() : standardDefaultDrumset();

Drumset defaultLayout = m_padListModel->constructDefaultLayout(defaultDrumset);
if (defaultLayout == *m_padListModel->drumset()) {
Expand All @@ -514,6 +512,45 @@ void PercussionPanelModel::resetLayout()
undoStack->commitChanges();
}

Drumset PercussionPanelModel::standardDefaultDrumset() const
{
const std::pair<Instrument*, Part*> instAndPart = getCurrentInstrumentAndPart();
const Instrument* inst = instAndPart.first;
const Part* part = instAndPart.second;

IF_ASSERT_FAILED(inst && inst->drumset() && part) {
return Drumset();
}

const InstrumentTemplate& instTemplate = instrumentsRepository()->instrumentTemplate(inst->id());
IF_ASSERT_FAILED(instTemplate.drumset) {
return Drumset();
}

return *instTemplate.drumset;
}

Drumset PercussionPanelModel::museSamplerDefaultDrumset() const
{
IF_ASSERT_FAILED(audioSettings()) {
return Drumset();
}

const muse::audio::AudioResourceMeta& resourceMeta = audioSettings()->trackInputParams(currentTrackId()).resourceMeta;

const int instrumentId = resourceMeta.attributeVal(u"museUID").toInt();

const muse::ByteArray drumMapping = museSampler()->drumMapping(instrumentId);
IF_ASSERT_FAILED(!drumMapping.empty()) {
return Drumset();
}

Drumset defaultDrumset;
PercussionUtilities::readDrumset(drumMapping, defaultDrumset);

return defaultDrumset;
}

InstrumentTrackId PercussionPanelModel::currentTrackId() const
{
if (!interaction()) {
Expand Down
4 changes: 4 additions & 0 deletions src/notation/view/percussionpanel/percussionpanelmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "context/iglobalcontext.h"
#include "actions/iactionsdispatcher.h"
#include "playback/iplaybackcontroller.h"
#include "musesampler/imusesamplerinfo.h"
#include "iinstrumentsrepository.h"
#include "inotationconfiguration.h"

Expand All @@ -54,6 +55,7 @@ class PercussionPanelModel : public QObject, public muse::Injectable, public mus
muse::Inject<context::IGlobalContext> globalContext = { this };
muse::Inject<muse::actions::IActionsDispatcher> dispatcher = { this };
muse::Inject<playback::IPlaybackController> playbackController = { this };
muse::Inject<muse::musesampler::IMuseSamplerInfo> museSampler;
muse::Inject<IInstrumentsRepository> instrumentsRepository = { this };
muse::Inject<INotationConfiguration> configuration = { this };

Expand Down Expand Up @@ -126,6 +128,8 @@ class PercussionPanelModel : public QObject, public muse::Injectable, public mus
void playPitch(int pitch);

void resetLayout();
Drumset standardDefaultDrumset() const;
Drumset museSamplerDefaultDrumset() const;

mu::engraving::InstrumentTrackId currentTrackId() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void PercussionPanelPadListModel::setDrumset(const engraving::Drumset* drumset)
removeEmptyRows();
}

mu::engraving::Drumset PercussionPanelPadListModel::constructDefaultLayout(const engraving::Drumset* defaultDrumset) const
mu::engraving::Drumset PercussionPanelPadListModel::constructDefaultLayout(const engraving::Drumset& defaultDrumset) const
{
//! NOTE: The idea of this method is take a "default" (template) drumset, find matching drums in the current drumset, and evaluate/return
//! the default panel layout based on this information. The reason we can't simply revert to the default drumset in its entirety is that
Expand All @@ -192,20 +192,20 @@ mu::engraving::Drumset PercussionPanelPadListModel::constructDefaultLayout(const
QList<int /*pitch*/> noTemplateFound;

for (int pitch = 0; pitch < mu::engraving::DRUM_INSTRUMENTS; ++pitch) {
if (defaultDrumset->isValid(pitch) && !defaultLayout.isValid(pitch)) {
if (defaultDrumset.isValid(pitch) && !defaultLayout.isValid(pitch)) {
// Pitch was deleted - restore it...
defaultLayout.drum(pitch) = defaultDrumset->drum(pitch);
defaultLayout.drum(pitch) = defaultDrumset.drum(pitch);
continue;
}
//! NOTE: Pitch + drum name isn't exactly the most robust identifier, but this will probably change with the new percussion ID system
if (!defaultDrumset->isValid(pitch) || defaultLayout.name(pitch) != defaultDrumset->name(pitch)) {
if (!defaultDrumset.isValid(pitch) || defaultLayout.name(pitch) != defaultDrumset.name(pitch)) {
// Drum is valid, but we can't find a template for it. Set the position chromatically later...
noTemplateFound.emplaceBack(pitch);
continue;
}

const int templateRow = defaultDrumset->drum(pitch).panelRow;
const int templateColumn = defaultDrumset->drum(pitch).panelColumn;
const int templateRow = defaultDrumset.drum(pitch).panelRow;
const int templateColumn = defaultDrumset.drum(pitch).panelColumn;

defaultLayout.drum(pitch).panelRow = templateRow;
defaultLayout.drum(pitch).panelColumn = templateColumn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class PercussionPanelPadListModel : public QAbstractListModel, public muse::Inje

QList<PercussionPanelPadModel*> padList() const { return m_padModels; }

mu::engraving::Drumset constructDefaultLayout(const engraving::Drumset* templateDrumset) const;
mu::engraving::Drumset constructDefaultLayout(const engraving::Drumset& templateDrumset) const;
int nextAvailableIndex(int pitch) const; //! NOTE: This may be equal to m_padModels.size()
int nextAvailablePitch(int pitch) const;

Expand Down
22 changes: 2 additions & 20 deletions src/playback/internal/drumsetloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
#include "drumsetloader.h"

#include "notation/notationtypes.h"

#include "engraving/rw/xmlreader.h"
#include "notation/utilities/percussionutilities.h"

#include "global/types/bytearray.h"

Expand All @@ -33,23 +32,6 @@ using namespace muse::audio;
using namespace mu::notation;
using namespace mu::engraving;

static void readDrumset(const muse::ByteArray& drumMapping, Drumset& drumset)
{
XmlReader reader(drumMapping);

while (reader.readNextStartElement()) {
if (reader.name() == "museScore") {
while (reader.readNextStartElement()) {
if (reader.name() == "Drum") {
drumset.load(reader);
} else {
reader.unknown();
}
}
}
}
}

void DrumsetLoader::loadDrumset(INotationPtr notation, const InstrumentTrackId& trackId, const AudioResourceMeta& resourceMeta)
{
TRACEFUNC;
Expand Down Expand Up @@ -93,7 +75,7 @@ void DrumsetLoader::loadDrumset(INotationPtr notation, const InstrumentTrackId&
}

Drumset drumset;
readDrumset(drumMapping, drumset);
PercussionUtilities::readDrumset(drumMapping, drumset);
replaceDrumset(notation, trackId, drumset);

m_drumsetCache.emplace(instrumentId, std::move(drumset));
Expand Down

0 comments on commit 07b47b9

Please sign in to comment.