Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MU4] Ported #6479, #6880: Automatic score ordering and bracketing #7402

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/libmscore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ set(MODULE_SRC
scoreElement.cpp
scoreElement.h
scorefile.cpp
scoreOrder.cpp
scoreOrder.h
score.h
scoretree.cpp
segment.cpp
Expand Down
169 changes: 168 additions & 1 deletion src/libmscore/instrtemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@
#include "style.h"
#include "sym.h"
#include "stringdata.h"
#include "scoreOrder.h"
#include "utils.h"
#include "xml.h"

namespace Ms {
QList<InstrumentGroup*> instrumentGroups;
QList<MidiArticulation> articulation; // global articulations
QList<InstrumentGenre*> instrumentGenres;
QList<InstrumentFamily*> instrumentFamilies;

//---------------------------------------------------------
// searchGenre
// searchInstrumentGenre
//---------------------------------------------------------

static InstrumentGenre* searchInstrumentGenre(const QString& genre)
Expand All @@ -39,6 +41,20 @@ static InstrumentGenre* searchInstrumentGenre(const QString& genre)
return nullptr;
}

//---------------------------------------------------------
// searchInstrumentFamily
//---------------------------------------------------------

static InstrumentFamily* searchInstrumentFamily(const QString& name)
{
for (InstrumentFamily* fam : qAsConst(instrumentFamilies)) {
if (fam->id == name) {
return fam;
}
}
return nullptr;
}

//---------------------------------------------------------
// searchInstrumentGroup
//---------------------------------------------------------
Expand Down Expand Up @@ -152,6 +168,7 @@ InstrumentTemplate::InstrumentTemplate()
drumset = 0;
extended = false;
singleNoteDynamics = true;
family = nullptr;

for (int i = 0; i < MAX_STAVES; ++i) {
clefTypes[i]._concertClef = ClefType::G;
Expand Down Expand Up @@ -207,6 +224,7 @@ void InstrumentTemplate::init(const InstrumentTemplate& t)
stringData = t.stringData;
midiActions = t.midiActions;
channel = t.channel;
family = t.family;
singleNoteDynamics = t.singleNoteDynamics;
}

Expand Down Expand Up @@ -334,6 +352,9 @@ void InstrumentTemplate::write(XmlWriter& xml) const
ma.write(xml);
}
}
if (!family) {
xml.tag("family", family->id);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #6479 (review)

needs sync after fix in the 3.x

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved in PR #7405.

xml.etag();
}

Expand Down Expand Up @@ -509,6 +530,8 @@ void InstrumentTemplate::read(XmlReader& e)
}
} else if (tag == "musicXMLid") {
musicXMLid = e.readElementText();
} else if (tag == "family") {
family = searchInstrumentFamily(e.readElementText());
} else if (tag == "genre") {
QString val(e.readElementText());
linkGenre(val);
Expand Down Expand Up @@ -578,6 +601,8 @@ void clearInstrumentTemplates()
instrumentGroups.clear();
qDeleteAll(instrumentGenres);
instrumentGenres.clear();
qDeleteAll(instrumentFamilies);
instrumentFamilies.clear();
articulation.clear();
}

Expand Down Expand Up @@ -620,6 +645,14 @@ bool loadInstrumentTemplates(const QString& instrTemplates)
instrumentGenres.append(genre);
}
genre->read(e);
} else if (tag == "Family") {
QString idFamily(e.attribute("id"));
InstrumentFamily* fam = searchInstrumentFamily(idFamily);
if (!fam) {
fam = new InstrumentFamily;
instrumentFamilies.append(fam);
}
fam->read(e);
} else {
e.unknown();
}
Expand Down Expand Up @@ -662,6 +695,105 @@ InstrumentTemplate* searchTemplateForMusicXmlId(const QString& mxmlId)
return 0;
}

InstrumentTemplate* searchTemplateForInstrNameList(const QList<QString>& nameList)
{
for (InstrumentGroup* g : qAsConst(instrumentGroups)) {
for (InstrumentTemplate* it : qAsConst(g->instrumentTemplates)) {
for (const QString& name : nameList) {
if (it->trackName == name
|| it->longNames.contains(StaffName(name))
|| it->shortNames.contains(StaffName(name))) {
return it;
}
}
}
}
return nullptr;
}

InstrumentTemplate* searchTemplateForMidiProgram(int midiProgram, const bool useDrumSet)
{
for (InstrumentGroup* g : qAsConst(instrumentGroups)) {
for (InstrumentTemplate* it : qAsConst(g->instrumentTemplates)) {
if (it->channel.empty() || it->useDrumset != useDrumSet) {
continue;
}

if (it->channel[0].program() == midiProgram) {
return it;
}
}
}
return 0;
}

InstrumentTemplate* guessTemplateByNameData(const QList<QString>& nameDataList)
{
for (InstrumentGroup* g : qAsConst(instrumentGroups)) {
for (InstrumentTemplate* it : qAsConst(g->instrumentTemplates)) {
for (const QString& name : nameDataList) {
if (name.contains(it->trackName, Qt::CaseInsensitive)
|| name.contains(it->longNames.value(0).name(), Qt::CaseInsensitive)
|| name.contains(it->shortNames.value(0).name(), Qt::CaseInsensitive)) {
return it;
}
}
}
}

for (const QString& name : nameDataList) {
if (name.contains("drum", Qt::CaseInsensitive)) {
return searchTemplate("drumset");
}

if (name.contains("piano", Qt::CaseInsensitive)) {
return searchTemplate("piano");
}
}

return nullptr;
}

//---------------------------------------------------------
// searchTemplateIndexForTrackName
//---------------------------------------------------------

InstrumentIndex searchTemplateIndexForTrackName(const QString& trackName)
{
int instIndex = 0;
int grpIndex = 0;
for (InstrumentGroup* g : qAsConst(instrumentGroups)) {
for (InstrumentTemplate* it : qAsConst(g->instrumentTemplates)) {
if (it->trackName == trackName) {
return InstrumentIndex(grpIndex, instIndex, it);
}
++instIndex;
}
++grpIndex;
}
return InstrumentIndex(-1, -1, nullptr);
}

//---------------------------------------------------------
// searchTemplateIndexForId
//---------------------------------------------------------

InstrumentIndex searchTemplateIndexForId(const QString& id)
{
int instIndex = 0;
int grpIndex = 0;
for (InstrumentGroup* g : instrumentGroups) {
for (InstrumentTemplate* it : g->instrumentTemplates) {
if (it->id == id) {
return InstrumentIndex(grpIndex, instIndex, it);
}
++instIndex;
}
++grpIndex;
}
return InstrumentIndex(-1, -1, nullptr);
}

//---------------------------------------------------------
// linkGenre
// link the current instrument template to the genre list specified by "genre"
Expand Down Expand Up @@ -719,6 +851,41 @@ void InstrumentGenre::read(XmlReader& e)
}
}

//---------------------------------------------------------
// familyMember
// is this instrument template a member of the supplied family
//---------------------------------------------------------

bool InstrumentTemplate::familyMember(const QString& name)
{
return family->id == name;
}

void InstrumentFamily::write(XmlWriter& xml) const
{
xml.stag(QString("Family id=\"%1\"").arg(id));
xml.tag("name", name);
xml.etag();
}

void InstrumentFamily::write1(XmlWriter& xml) const
{
write(xml);
}

void InstrumentFamily::read(XmlReader& e)
{
id = e.attribute("id");
while (e.readNextStartElement()) {
const QStringRef& tag(e.name());
if (tag == "name") {
name = qApp->translate("InstrumentsXML", e.readElementText().toUtf8().data());
} else {
e.unknown();
}
}
}

//---------------------------------------------------------
// clefType
//---------------------------------------------------------
Expand Down
39 changes: 39 additions & 0 deletions src/libmscore/instrtemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ class InstrumentGenre
void read(XmlReader&);
};

//---------------------------------------------------------
// InstrumentFamily
//---------------------------------------------------------

class InstrumentFamily
{
public:
QString id;
QString name;

InstrumentFamily() {}
void write(XmlWriter& xml) const;
void write1(XmlWriter& xml) const;
void read(XmlReader&);
};

//---------------------------------------------------------
// InstrumentTemplate
//---------------------------------------------------------
Expand Down Expand Up @@ -75,6 +91,7 @@ class InstrumentTemplate
QList<MidiArticulation> articulation;
QList<Channel> channel;
QList<InstrumentGenre*> genres; //; list of genres this instrument belongs to
InstrumentFamily* family; //; family the instrument belongs to

ClefTypeList clefTypes[MAX_STAVES];
int staffLines[MAX_STAVES];
Expand All @@ -94,6 +111,7 @@ class InstrumentTemplate
void linkGenre(const QString&);
void addGenre(QList<InstrumentGenre*>);
bool genreMember(const QString&);
bool familyMember(const QString&);

void setPitchRange(const QString& s, char* a, char* b) const;
void write(XmlWriter& xml) const;
Expand All @@ -119,13 +137,34 @@ struct InstrumentGroup {
InstrumentGroup() { extended = false; }
};

//---------------------------------------------------------
// InstrumentIndex
//---------------------------------------------------------

struct InstrumentIndex {
int groupIndex;
int instrIndex;
InstrumentTemplate* instrTemplate;

InstrumentIndex(int g, int i, InstrumentTemplate* it)
: groupIndex{g}, instrIndex{i}, instrTemplate{it} {}
};

extern QList<InstrumentGenre*> instrumentGenres;
extern QList<InstrumentFamily*> instrumentFamilies;
extern QList<MidiArticulation> articulation;
extern QList<InstrumentGroup*> instrumentGroups;
extern void clearInstrumentTemplates();
extern bool loadInstrumentTemplates(const QString& instrTemplates);
extern bool saveInstrumentTemplates(const QString& instrTemplates);
extern InstrumentTemplate* searchTemplate(const QString& name);
extern InstrumentIndex searchTemplateIndexForTrackName(const QString& trackName);
extern InstrumentIndex searchTemplateIndexForId(const QString& id);
extern InstrumentTemplate* searchTemplateForMusicXmlId(const QString& mxmlId);
extern InstrumentTemplate* searchTemplateForInstrNameList(const QList<QString>& nameList);
extern InstrumentTemplate* searchTemplateForMidiProgram(int midiProgram, const bool useDrumKit = false);
extern InstrumentTemplate* guessTemplateByNameData(const QList<QString>& nameDataList);
extern InstrumentGroup* searchInstrumentGroup(const QString& name);
extern ClefType defaultClef(int patch);
} // namespace Ms
#endif
Loading