diff --git a/src/engraving/libmscore/instrument.cpp b/src/engraving/libmscore/instrument.cpp index 265fa8b987..124d312dde 100644 --- a/src/engraving/libmscore/instrument.cpp +++ b/src/engraving/libmscore/instrument.cpp @@ -364,138 +364,6 @@ int Instrument::recognizeMidiProgram() const return 0; } -//--------------------------------------------------------- -// Instrument::read -//--------------------------------------------------------- - -void Instrument::read(XmlReader& e, Part* part) -{ - bool customDrumset = false; - bool readSingleNoteDynamics = false; - - _channel.clear(); // remove default channel - _id = e.attribute("id"); - while (e.readNextStartElement()) { - const AsciiStringView tag(e.name()); - if (tag == "singleNoteDynamics") { - _singleNoteDynamics = e.readBool(); - readSingleNoteDynamics = true; - } else if (!readProperties(e, part, &customDrumset)) { - e.unknown(); - } - } - - if (_musicXmlId.isEmpty()) { - _musicXmlId = recognizeMusicXmlId(); - } - - if (_id.isEmpty()) { - _id = recognizeId(); - } - - if (channel(0) && channel(0)->program() == -1) { - channel(0)->setProgram(recognizeMidiProgram()); - } - - if (!readSingleNoteDynamics) { - setSingleNoteDynamicsFromTemplate(); - } -} - -//--------------------------------------------------------- -// Instrument::readProperties -//--------------------------------------------------------- - -bool Instrument::readProperties(XmlReader& e, Part* part, bool* customDrumset) -{ - PartAudioSettingsCompat partAudioSetting; - InstrumentTrackId trackId; - if (part && part->score()) { - trackId = { part->score()->parts().size() + 1, id().toStdString() };//part is not assigned to score, _id field is not correct - } - partAudioSetting.instrumentId = trackId; - const AsciiStringView tag(e.name()); - if (tag == "longName") { - StaffName name; - rw400::TRead::read(&name, e); - _longNames.push_back(name); - } else if (tag == "shortName") { - StaffName name; - rw400::TRead::read(&name, e); - _shortNames.push_back(name); - } else if (tag == "trackName") { - _trackName = e.readText(); - } else if (tag == "minPitch") { // obsolete - _minPitchP = _minPitchA = e.readInt(); - } else if (tag == "maxPitch") { // obsolete - _maxPitchP = _maxPitchA = e.readInt(); - } else if (tag == "minPitchA") { - _minPitchA = e.readInt(); - } else if (tag == "minPitchP") { - _minPitchP = e.readInt(); - } else if (tag == "maxPitchA") { - _maxPitchA = e.readInt(); - } else if (tag == "maxPitchP") { - _maxPitchP = e.readInt(); - } else if (tag == "transposition") { // obsolete - _transpose.chromatic = e.readInt(); - _transpose.diatonic = chromatic2diatonic(_transpose.chromatic); - } else if (tag == "transposeChromatic") { - _transpose.chromatic = e.readInt(); - } else if (tag == "transposeDiatonic") { - _transpose.diatonic = e.readInt(); - } else if (tag == "instrumentId") { - _musicXmlId = e.readText(); - } else if (tag == "useDrumset") { - _useDrumset = e.readInt(); - if (_useDrumset) { - delete _drumset; - _drumset = new Drumset(*smDrumset); - } - } else if (tag == "Drum") { - // if we see on of this tags, a custom drumset will - // be created - if (!_drumset) { - _drumset = new Drumset(*smDrumset); - } - if (!(*customDrumset)) { - const_cast(_drumset)->clear(); - *customDrumset = true; - } - const_cast(_drumset)->load(e); - } - // support tag "Tablature" for a while for compatibility with existent 2.0 scores - else if (tag == "Tablature" || tag == "StringData") { - _stringData.read(e); - } else if (tag == "MidiAction") { - NamedEventList a; - a.read(e); - _midiActions.push_back(a); - } else if (tag == "Articulation") { - MidiArticulation a; - a.read(e); - _articulation.push_back(a); - } else if (tag == "Channel" || tag == "channel") { - InstrChannel* a = new InstrChannel; - a->read(e, part, trackId); - _channel.push_back(a); - } else if (tag == "clef") { // sets both transposing and concert clef - int idx = e.intAttribute("staff", 1) - 1; - ClefType ct = TConv::fromXml(e.readAsciiText(), ClefType::G); - setClefType(idx, ClefTypeList(ct, ct)); - } else if (tag == "concertClef") { - int idx = e.intAttribute("staff", 1) - 1; - setClefType(idx, ClefTypeList(TConv::fromXml(e.readAsciiText(), ClefType::G), clefType(idx)._transposingClef)); - } else if (tag == "transposingClef") { - int idx = e.intAttribute("staff", 1) - 1; - setClefType(idx, ClefTypeList(clefType(idx)._concertClef, TConv::fromXml(e.readAsciiText(), ClefType::G))); - } else { - return false; - } - - return true; -} - //--------------------------------------------------------- // action //--------------------------------------------------------- @@ -1511,6 +1379,16 @@ const StaffNameList& Instrument::shortNames() const return _shortNames; } +void Instrument::appendLongName(const StaffName& n) +{ + _longNames.push_back(n); +} + +void Instrument::appendShortName(const StaffName& n) +{ + _shortNames.push_back(n); +} + //--------------------------------------------------------- // trackName //--------------------------------------------------------- diff --git a/src/engraving/libmscore/instrument.h b/src/engraving/libmscore/instrument.h index 58e99472fa..8eb34824a6 100644 --- a/src/engraving/libmscore/instrument.h +++ b/src/engraving/libmscore/instrument.h @@ -327,8 +327,6 @@ public: Instrument(const Instrument&); ~Instrument(); - void read(XmlReader&, Part* part); - bool readProperties(XmlReader&, Part*, bool* customDrumset); NamedEventList* midiAction(const String& s, int channel) const; int channelIdx(const String& s) const; void updateVelocity(int* velocity, int channel, const String& name); @@ -372,7 +370,10 @@ public: void setClefType(size_t staffIdx, const ClefTypeList& c); const std::list& midiActions() const { return _midiActions; } + void addMidiAction(const NamedEventList& l) { _midiActions.push_back(l); } + const std::vector& articulation() const { return _articulation; } + void addMidiArticulation(const MidiArticulation& a) { _articulation.push_back(a); } const std::vector& channel() const { return _channel; } void appendChannel(InstrChannel* c) { _channel.push_back(c); } @@ -401,6 +402,8 @@ public: const StaffNameList& shortNames() const; void setLongNames(const StaffNameList& l); void setShortNames(const StaffNameList& l); + void appendLongName(const StaffName& n); + void appendShortName(const StaffName& n); String trackName() const; void setTrackName(const String& s); diff --git a/src/engraving/rw/114/read114.cpp b/src/engraving/rw/114/read114.cpp index c44eb09bc5..ef87ea28f0 100644 --- a/src/engraving/rw/114/read114.cpp +++ b/src/engraving/rw/114/read114.cpp @@ -2477,7 +2477,7 @@ static void readInstrument(Instrument* i, Part* p, XmlReader& e) customDrumset = true; } readDrumset(i->drumset(), e); - } else if (i->readProperties(e, p, &customDrumset)) { + } else if (rw400::TRead::readProperties(i, e, p, &customDrumset)) { } else { e.unknown(); } diff --git a/src/engraving/rw/206/read206.cpp b/src/engraving/rw/206/read206.cpp index 2d28a829fb..62dbfdd1da 100644 --- a/src/engraving/rw/206/read206.cpp +++ b/src/engraving/rw/206/read206.cpp @@ -682,7 +682,7 @@ static void readInstrument206(Instrument* i, Part* p, XmlReader& e) customDrumset = true; } readDrumset206(i->drumset(), e); - } else if (i->readProperties(e, p, &customDrumset)) { + } else if (rw400::TRead::readProperties(i, e, p, &customDrumset)) { } else { e.unknown(); } diff --git a/src/engraving/rw/400/tread.cpp b/src/engraving/rw/400/tread.cpp index 0d80f15331..b1c40112a4 100644 --- a/src/engraving/rw/400/tread.cpp +++ b/src/engraving/rw/400/tread.cpp @@ -35,7 +35,10 @@ #include "../../libmscore/tempotext.h" #include "../../libmscore/stafftext.h" #include "../../libmscore/stafftextbase.h" + +#include "../../libmscore/drumset.h" #include "../../libmscore/dynamic.h" + #include "../../libmscore/harmony.h" #include "../../libmscore/chordlist.h" @@ -714,13 +717,150 @@ void TRead::read(RehearsalMark* m, XmlReader& xml, ReadContext& ctx) read(static_cast(m), xml, ctx); } +void TRead::read(Instrument* item, XmlReader& e, ReadContext&, Part* part) +{ + bool customDrumset = false; + bool readSingleNoteDynamics = false; + + item->clearChannels(); // remove default channel + item->setId(e.attribute("id")); + while (e.readNextStartElement()) { + const AsciiStringView tag(e.name()); + if (tag == "singleNoteDynamics") { + item->setSingleNoteDynamics(e.readBool()); + readSingleNoteDynamics = true; + } else if (!readProperties(item, e, part, &customDrumset)) { + e.unknown(); + } + } + + if (item->musicXmlId().isEmpty()) { + item->setMusicXmlId(item->recognizeMusicXmlId()); + } + + if (item->id().isEmpty()) { + item->setId(item->recognizeId()); + } + + if (item->channel(0) && item->channel(0)->program() == -1) { + item->channel(0)->setProgram(item->recognizeMidiProgram()); + } + + if (!readSingleNoteDynamics) { + item->setSingleNoteDynamicsFromTemplate(); + } +} + +bool TRead::readProperties(Instrument* item, XmlReader& e, Part* part, bool* customDrumset) +{ + PartAudioSettingsCompat partAudioSetting; + InstrumentTrackId trackId; + if (part && part->score()) { + trackId = { part->score()->parts().size() + 1, item->id().toStdString() };//part is not assigned to score, _id field is not correct + } + partAudioSetting.instrumentId = trackId; + + const AsciiStringView tag(e.name()); + if (tag == "longName") { + StaffName name; + TRead::read(&name, e); + item->appendLongName(name); + } else if (tag == "shortName") { + StaffName name; + TRead::read(&name, e); + item->appendShortName(name); + } else if (tag == "trackName") { + item->setTrackName(e.readText()); + } else if (tag == "minPitch") { // obsolete + int pitch = e.readInt(); + item->setMinPitchP(pitch); + item->setMinPitchA(pitch); + } else if (tag == "maxPitch") { // obsolete + int pitch = e.readInt(); + item->setMaxPitchP(pitch); + item->setMaxPitchA(pitch); + } else if (tag == "minPitchA") { + item->setMinPitchA(e.readInt()); + } else if (tag == "minPitchP") { + item->setMinPitchP(e.readInt()); + } else if (tag == "maxPitchA") { + item->setMaxPitchA(e.readInt()); + } else if (tag == "maxPitchP") { + item->setMaxPitchP(e.readInt()); + } else if (tag == "transposition") { // obsolete + Interval transpose; + transpose.chromatic = e.readInt(); + transpose.diatonic = chromatic2diatonic(transpose.chromatic); + item->setTranspose(transpose); + } else if (tag == "transposeChromatic") { + Interval transpose = item->transpose(); + transpose.chromatic = e.readInt(); + item->setTranspose(transpose); + } else if (tag == "transposeDiatonic") { + Interval transpose = item->transpose(); + transpose.diatonic = e.readInt(); + item->setTranspose(transpose); + } else if (tag == "instrumentId") { + item->setMusicXmlId(e.readText()); + } else if (tag == "useDrumset") { + item->setUseDrumset(e.readInt()); + if (item->useDrumset()) { + delete item->drumset(); + item->setDrumset(new Drumset(*smDrumset)); + } + } else if (tag == "Drum") { + // if we see on of this tags, a custom drumset will + // be created + if (!item->drumset()) { + item->setDrumset(new Drumset(*smDrumset)); + } + if (!(*customDrumset)) { + const_cast(item->drumset())->clear(); + *customDrumset = true; + } + const_cast(item->drumset())->load(e); + } + // support tag "Tablature" for a while for compatibility with existent 2.0 scores + else if (tag == "Tablature" || tag == "StringData") { + StringData sd; + sd.read(e); + item->setStringData(sd); + } else if (tag == "MidiAction") { + NamedEventList a; + a.read(e); + item->addMidiAction(a); + } else if (tag == "Articulation") { + MidiArticulation a; + a.read(e); + item->addMidiArticulation(a); + } else if (tag == "Channel" || tag == "channel") { + InstrChannel* a = new InstrChannel; + a->read(e, part, trackId); + item->appendChannel(a); + } else if (tag == "clef") { // sets both transposing and concert clef + int idx = e.intAttribute("staff", 1) - 1; + ClefType ct = TConv::fromXml(e.readAsciiText(), ClefType::G); + item->setClefType(idx, ClefTypeList(ct, ct)); + } else if (tag == "concertClef") { + int idx = e.intAttribute("staff", 1) - 1; + item->setClefType(idx, ClefTypeList(TConv::fromXml(e.readAsciiText(), ClefType::G), item->clefType(idx)._transposingClef)); + } else if (tag == "transposingClef") { + int idx = e.intAttribute("staff", 1) - 1; + item->setClefType(idx, ClefTypeList(item->clefType(idx)._concertClef, TConv::fromXml(e.readAsciiText(), ClefType::G))); + } else { + return false; + } + + return true; +} + void TRead::read(InstrumentChange* c, XmlReader& e, ReadContext& ctx) { Instrument inst; while (e.readNextStartElement()) { const AsciiStringView tag(e.name()); if (tag == "Instrument") { - inst.read(e, c->part()); + read(&inst, e, ctx, c->part()); } else if (tag == "init") { c->setInit(e.readBool()); } else if (!readProperties(static_cast(c), e, ctx)) { @@ -948,7 +1088,7 @@ void TRead::read(StaffState* s, XmlReader& e, ReadContext& ctx) s->setStaffStateType(StaffStateType(e.readInt())); } else if (tag == "Instrument") { Instrument i; - i.read(e, nullptr); + read(&i, e, ctx, nullptr); s->setInstrument(std::move(i)); } else if (!readItemProperties(s, e, ctx)) { e.unknown(); @@ -1045,25 +1185,25 @@ void TRead::read(Fermata* f, XmlReader& e, ReadContext& ctx) } } -bool TRead::readProperties(Fermata* f, XmlReader& e, ReadContext& ctx) +bool TRead::readProperties(Fermata* f, XmlReader& xml, ReadContext& ctx) { - const AsciiStringView tag(e.name()); + const AsciiStringView tag(xml.name()); if (tag == "subtype") { - AsciiStringView s = e.readAsciiText(); + AsciiStringView s = xml.readAsciiText(); SymId id = SymNames::symIdByName(s); f->setSymId(id); } else if (tag == "play") { - f->setPlay(e.readBool()); + f->setPlay(xml.readBool()); } else if (tag == "timeStretch") { - f->setTimeStretch(e.readDouble()); + f->setTimeStretch(xml.readDouble()); } else if (tag == "offset") { if (f->score()->mscVersion() > 114) { - readItemProperties(f, e, ctx); + readItemProperties(f, xml, ctx); } else { - e.skipCurrentElement(); // ignore manual layout in older scores + xml.skipCurrentElement(); // ignore manual layout in older scores } - } else if (readItemProperties(f, e, ctx)) { + } else if (readItemProperties(f, xml, ctx)) { } else { return false; } @@ -2779,7 +2919,7 @@ bool TRead::readProperties(Part* p, XmlReader& e, ReadContext& ctx) TRead::read(staff, e, ctx); } else if (tag == "Instrument") { Instrument* instr = new Instrument; - instr->read(e, p); + read(instr, e, ctx, p); p->setInstrument(instr, Fraction(-1, 1)); } else if (tag == "name") { p->instrument()->setLongName(e.readText()); diff --git a/src/engraving/rw/400/tread.h b/src/engraving/rw/400/tread.h index 01a8df437d..1e0d766f9d 100644 --- a/src/engraving/rw/400/tread.h +++ b/src/engraving/rw/400/tread.h @@ -206,6 +206,8 @@ public: static void read(Groups* g, XmlReader& xml, ReadContext& ctx); static void read(Hairpin* h, XmlReader& xml, ReadContext& ctx); static void read(Hook* h, XmlReader& xml, ReadContext& ctx); + + static void read(Instrument* item, XmlReader& xml, ReadContext& ctx, Part* part); static void read(InstrumentChange* c, XmlReader& xml, ReadContext& ctx); static void read(KeyList* item, XmlReader& xml, ReadContext& ctx); @@ -285,7 +287,10 @@ public: static bool readProperties(Chord* ch, XmlReader& xml, ReadContext& ctx); static bool readProperties(ChordRest* ch, XmlReader& xml, ReadContext& ctx); static bool readProperties(Clef* c, XmlReader& xml, ReadContext& ctx); - static bool readProperties(Fermata* f, XmlReader& e, ReadContext& ctx); + static bool readProperties(Fermata* f, XmlReader& xml, ReadContext& ctx); + + static bool readProperties(Instrument* item, XmlReader& xml, Part* part, bool* customDrumset); + static bool readProperties(LedgerLine* l, XmlReader& xml, ReadContext& ctx); static bool readProperties(LineSegment* l, XmlReader& xml, ReadContext& ctx); static bool readProperties(Lyrics* l, XmlReader& xml, ReadContext& ctx);