Skip to content

Commit

Permalink
ported #6479, #6880: Automatic score ordering and bracketing
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkorsukov authored and vpereverzev committed Feb 3, 2021
1 parent 6c68edc commit e0f5ec3
Show file tree
Hide file tree
Showing 15 changed files with 1,555 additions and 10 deletions.
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);
}
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

0 comments on commit e0f5ec3

Please sign in to comment.