1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2008-2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "instrument.h"
14 #include "xml.h"
15 #include "drumset.h"
16 #include "articulation.h"
17 #include "utils.h"
18 #include "stringdata.h"
19 #include "instrtemplate.h"
20 #include "mscore.h"
21 #include "part.h"
22 #include "score.h"
23 
24 #include "audio/midi/synthesizer.h"
25 #include "audio/midi/midipatch.h"
26 
27 namespace Ms {
28 
29 //: Channel name for otherwise unamed channels
30 const char* Channel::DEFAULT_NAME = QT_TRANSLATE_NOOP("InstrumentsXML", "normal");
31 //: Channel name for the chord symbols playback channel, best keep translation shorter than 11 letters
32 const char* Channel::HARMONY_NAME = QT_TRANSLATE_NOOP("InstrumentsXML", "harmony");
33 
34 Instrument InstrumentList::defaultInstrument;
35 const std::initializer_list<Channel::Prop> PartChannelSettingsLink::excerptProperties {
36       Channel::Prop::SOLOMUTE,
37       Channel::Prop::SOLO,
38       Channel::Prop::MUTE,
39       };
40 
41 //---------------------------------------------------------
42 //   write
43 //---------------------------------------------------------
44 
write(XmlWriter & xml,const QString & n) const45 void NamedEventList::write(XmlWriter& xml, const QString& n) const
46       {
47       xml.stag(QString("%1 name=\"%2\"").arg(n, name));
48       if (!descr.isEmpty())
49             xml.tag("descr", descr);
50       for (const MidiCoreEvent& e : events)
51             e.write(xml);
52       xml.etag();
53       }
54 
55 //---------------------------------------------------------
56 //   read
57 //---------------------------------------------------------
58 
read(XmlReader & e)59 void NamedEventList::read(XmlReader& e)
60       {
61       name = e.attribute("name");
62       while (e.readNextStartElement()) {
63             const QStringRef& tag(e.name());
64             if (tag == "program") {
65                   MidiCoreEvent ev(ME_CONTROLLER, 0, CTRL_PROGRAM, e.intAttribute("value", 0));
66                   events.push_back(ev);
67                   e.skipCurrentElement();
68                   }
69             else if (tag == "controller") {
70                   MidiCoreEvent ev;
71                   ev.setType(ME_CONTROLLER);
72                   ev.setDataA(e.intAttribute("ctrl", 0));
73                   ev.setDataB(e.intAttribute("value", 0));
74                   events.push_back(ev);
75                   e.skipCurrentElement();
76                   }
77             else if (tag == "descr")
78                   descr = e.readElementText();
79             else
80                   e.unknown();
81             }
82       }
83 
84 //---------------------------------------------------------
85 //   operator
86 //---------------------------------------------------------
87 
operator ==(const MidiArticulation & i) const88 bool MidiArticulation::operator==(const MidiArticulation& i) const
89       {
90       return (i.name == name) && (i.velocity == velocity) && (i.gateTime == gateTime);
91       }
92 
93 //---------------------------------------------------------
94 //   Instrument
95 //---------------------------------------------------------
96 
Instrument(QString id)97 Instrument::Instrument(QString id)
98       {
99       _id = id;
100       Channel* a = new Channel;
101       a->setName(Channel::DEFAULT_NAME);
102       _channel.append(a);
103 
104       _minPitchA   = 0;
105       _maxPitchA   = 127;
106       _minPitchP   = 0;
107       _maxPitchP   = 127;
108       _useDrumset  = false;
109       _drumset     = 0;
110       _singleNoteDynamics = true;
111       }
112 
Instrument(const Instrument & i)113 Instrument::Instrument(const Instrument& i)
114       {
115       _id           = i._id;
116       _longNames    = i._longNames;
117       _shortNames   = i._shortNames;
118       _trackName    = i._trackName;
119       _minPitchA    = i._minPitchA;
120       _maxPitchA    = i._maxPitchA;
121       _minPitchP    = i._minPitchP;
122       _maxPitchP    = i._maxPitchP;
123       _transpose    = i._transpose;
124       _instrumentId = i._instrumentId;
125       _stringData   = i._stringData;
126       _drumset      = 0;
127       setDrumset(i._drumset);
128       _useDrumset   = i._useDrumset;
129       _stringData   = i._stringData;
130       _midiActions  = i._midiActions;
131       _articulation = i._articulation;
132       _singleNoteDynamics = i._singleNoteDynamics;
133       for (Channel* c : i._channel)
134             _channel.append(new Channel(*c));
135       _clefType     = i._clefType;
136       }
137 
operator =(const Instrument & i)138 void Instrument::operator=(const Instrument& i)
139       {
140       qDeleteAll(_channel);
141       _channel.clear();
142       delete _drumset;
143 
144       _id           = i._id;
145       _longNames    = i._longNames;
146       _shortNames   = i._shortNames;
147       _trackName    = i._trackName;
148       _minPitchA    = i._minPitchA;
149       _maxPitchA    = i._maxPitchA;
150       _minPitchP    = i._minPitchP;
151       _maxPitchP    = i._maxPitchP;
152       _transpose    = i._transpose;
153       _instrumentId = i._instrumentId;
154       _stringData   = i._stringData;
155       _drumset      = 0;
156       setDrumset(i._drumset);
157       _useDrumset   = i._useDrumset;
158       _stringData   = i._stringData;
159       _midiActions  = i._midiActions;
160       _articulation = i._articulation;
161       _singleNoteDynamics = i._singleNoteDynamics;
162       for (Channel* c : i._channel)
163             _channel.append(new Channel(*c));
164       _clefType     = i._clefType;
165       }
166 
167 //---------------------------------------------------------
168 //   ~Instrument
169 //---------------------------------------------------------
170 
~Instrument()171 Instrument::~Instrument()
172       {
173       qDeleteAll(_channel);
174       delete _drumset;
175       }
176 
177 //---------------------------------------------------------
178 //   StaffName
179 //---------------------------------------------------------
180 
StaffName(const QString & s,int p)181 StaffName::StaffName(const QString& s, int p) : _name(s), _pos(p)
182       {
183       Text::validateText(_name); // enforce HTML encoding
184       }
185 
186 //---------------------------------------------------------
187 //   StaffName::write
188 //---------------------------------------------------------
189 
write(XmlWriter & xml,const char * tag) const190 void StaffName::write(XmlWriter& xml, const char* tag) const
191       {
192       if (!name().isEmpty()) {
193             if (pos() == 0)
194                   xml.writeXml(QString("%1").arg(tag), name());
195             else
196                   xml.writeXml(QString("%1 pos=\"%2\"").arg(tag).arg(pos()), name());
197             }
198       }
199 
200 //---------------------------------------------------------
201 //   read
202 //---------------------------------------------------------
203 
read(XmlReader & e)204 void StaffName::read(XmlReader& e)
205       {
206       _pos  = e.intAttribute("pos", 0);
207       _name = e.readXml();
208       if (_name.startsWith("<html>")) {
209             // compatibility to old html implementation:
210             _name = QTextDocumentFragment::fromHtml(_name).toPlainText();
211             }
212       }
213 
214 //---------------------------------------------------------
215 //   Instrument::write
216 //---------------------------------------------------------
217 
write(XmlWriter & xml,const Part * part) const218 void Instrument::write(XmlWriter& xml, const Part* part) const
219       {
220       if (_id.isEmpty())
221             xml.stag("Instrument");
222       else
223             xml.stag(QString("Instrument id=\"%1\"").arg(_id));
224       _longNames.write(xml, "longName");
225       _shortNames.write(xml, "shortName");
226 //      if (!_trackName.empty())
227             xml.tag("trackName", _trackName);
228       if (_minPitchP > 0)
229             xml.tag("minPitchP", _minPitchP);
230       if (_maxPitchP < 127)
231             xml.tag("maxPitchP", _maxPitchP);
232       if (_minPitchA > 0)
233             xml.tag("minPitchA", _minPitchA);
234       if (_maxPitchA < 127)
235             xml.tag("maxPitchA", _maxPitchA);
236       if (_transpose.diatonic)
237             xml.tag("transposeDiatonic", _transpose.diatonic);
238       if (_transpose.chromatic)
239             xml.tag("transposeChromatic", _transpose.chromatic);
240       if (!_instrumentId.isEmpty())
241             xml.tag("instrumentId", _instrumentId);
242       if (_useDrumset) {
243             xml.tag("useDrumset", _useDrumset);
244             _drumset->save(xml);
245             }
246       for (int i = 0; i < _clefType.size(); ++i) {
247             ClefTypeList ct = _clefType[i];
248             if (ct._concertClef == ct._transposingClef) {
249                   if (ct._concertClef != ClefType::G) {
250                         QString tag = ClefInfo::tag(ct._concertClef);
251                         if (i)
252                               xml.tag(QString("clef staff=\"%1\"").arg(i+1), tag);
253                         else
254                               xml.tag("clef", tag);
255                         }
256                   }
257             else {
258                   QString tag1 = ClefInfo::tag(ct._concertClef);
259                   QString tag2 = ClefInfo::tag(ct._transposingClef);
260                   if (i) {
261                         xml.tag(QString("concertClef staff=\"%1\"").arg(i+1), tag1);
262                         xml.tag(QString("transposingClef staff=\"%1\"").arg(i+1), tag2);
263                         }
264                   else {
265                         xml.tag("concertClef", tag1);
266                         xml.tag("transposingClef", tag2);
267                         }
268                   }
269             }
270 
271       if (_singleNoteDynamics != getSingleNoteDynamicsFromTemplate())
272             xml.tag("singleNoteDynamics", _singleNoteDynamics);
273 
274       if (!(_stringData == StringData()))
275             _stringData.write(xml);
276       for (const NamedEventList& a : _midiActions)
277             a.write(xml, "MidiAction");
278       for (const MidiArticulation& a : _articulation)
279             a.write(xml);
280       for (const Channel* a : _channel)
281             a->write(xml, part);
282       xml.etag();
283       }
284 
recognizeInstrumentId() const285 QString Instrument::recognizeInstrumentId() const
286       {
287       static QString defaultInstrumentId("keyboard.piano");
288 
289       QList<QString> nameList;
290 
291       nameList << _trackName;
292       nameList << _longNames.toStringList();
293       nameList << _shortNames.toStringList();
294 
295       InstrumentTemplate* tmplByName = Ms::searchTemplateForInstrNameList(nameList);
296 
297       if (tmplByName && !tmplByName->musicXMLid.isEmpty())
298             return tmplByName->musicXMLid;
299 
300       if (!channel(0))
301             return defaultInstrumentId;
302 
303       InstrumentTemplate* tmplMidiProgram = Ms::searchTemplateForMidiProgram(channel(0)->program(), useDrumset());
304 
305       if (tmplMidiProgram && !tmplMidiProgram->musicXMLid.isEmpty())
306             return tmplMidiProgram->musicXMLid;
307 
308       InstrumentTemplate* guessedTmpl = Ms::guessTemplateByNameData(nameList);
309 
310       if (guessedTmpl && !guessedTmpl->musicXMLid.isEmpty())
311             return guessedTmpl->musicXMLid;
312 
313       return defaultInstrumentId;
314       }
315 
recognizeMidiProgram() const316 int Instrument::recognizeMidiProgram() const
317       {
318       InstrumentTemplate* tmplInstrumentId = Ms::searchTemplateForMusicXmlId(_instrumentId);
319 
320       if (tmplInstrumentId && !tmplInstrumentId->channel.isEmpty() && tmplInstrumentId->channel[0].program() >= 0)
321             return tmplInstrumentId->channel[0].program();
322 
323       QList<QString> nameList;
324 
325       nameList << _trackName;
326       nameList << _longNames.toStringList();
327       nameList << _shortNames.toStringList();
328 
329       InstrumentTemplate* tmplByName = Ms::searchTemplateForInstrNameList(nameList);
330 
331       if (tmplByName && !tmplByName->channel.isEmpty() && tmplByName->channel[0].program() >= 0)
332             return tmplByName->channel[0].program();
333 
334       InstrumentTemplate* guessedTmpl = Ms::guessTemplateByNameData(nameList);
335 
336       if (guessedTmpl && !guessedTmpl->channel.isEmpty() && guessedTmpl->channel[0].program() >= 0)
337             return guessedTmpl->channel[0].program();
338 
339       return 0;
340       }
341 
342 //---------------------------------------------------------
343 //   Instrument::read
344 //---------------------------------------------------------
345 
read(XmlReader & e,Part * part)346 void Instrument::read(XmlReader& e, Part* part)
347       {
348       bool customDrumset = false;
349       bool readSingleNoteDynamics = false;
350 
351       _channel.clear();       // remove default channel
352       _id = e.attribute("id");
353       while (e.readNextStartElement()) {
354             const QStringRef& tag(e.name());
355             if (tag == "singleNoteDynamics") {
356                   _singleNoteDynamics = e.readBool();
357                   readSingleNoteDynamics = true;
358                   }
359             else if (!readProperties(e, part, &customDrumset))
360                   e.unknown();
361             }
362 
363       if (_instrumentId.isEmpty())
364             _instrumentId = recognizeInstrumentId();
365 
366       if (channel(0) && channel(0)->program() == -1) {
367           channel(0)->setProgram(recognizeMidiProgram());
368       }
369 
370       if (!readSingleNoteDynamics)
371             setSingleNoteDynamicsFromTemplate();
372 
373       if (_useDrumset) {
374             if (_channel[0]->bank() == 0 && _channel[0]->synti().toLower() != "zerberus")
375                   _channel[0]->setBank(128);
376             }
377       }
378 
379 //---------------------------------------------------------
380 //   Instrument::readProperties
381 //---------------------------------------------------------
382 
readProperties(XmlReader & e,Part * part,bool * customDrumset)383 bool Instrument::readProperties(XmlReader& e, Part* part, bool* customDrumset)
384       {
385       const QStringRef& tag(e.name());
386       if (tag == "longName") {
387             StaffName name;
388             name.read(e);
389             _longNames.append(name);
390             }
391       else if (tag == "shortName") {
392             StaffName name;
393             name.read(e);
394             _shortNames.append(name);
395             }
396       else if (tag == "trackName")
397             _trackName = e.readElementText();
398       else if (tag == "minPitch") {      // obsolete
399             _minPitchP = _minPitchA = e.readInt();
400             }
401       else if (tag == "maxPitch") {       // obsolete
402             _maxPitchP = _maxPitchA = e.readInt();
403             }
404       else if (tag == "minPitchA")
405             _minPitchA = e.readInt();
406       else if (tag == "minPitchP")
407             _minPitchP = e.readInt();
408       else if (tag == "maxPitchA")
409             _maxPitchA = e.readInt();
410       else if (tag == "maxPitchP")
411             _maxPitchP = e.readInt();
412       else if (tag == "transposition") {    // obsolete
413             _transpose.chromatic = e.readInt();
414             _transpose.diatonic = chromatic2diatonic(_transpose.chromatic);
415             }
416       else if (tag == "transposeChromatic")
417             _transpose.chromatic = e.readInt();
418       else if (tag == "transposeDiatonic")
419             _transpose.diatonic = e.readInt();
420       else if (tag == "instrumentId")
421             _instrumentId = e.readElementText();
422       else if (tag == "useDrumset") {
423             _useDrumset = e.readInt();
424             if (_useDrumset) {
425                   delete _drumset;
426                   _drumset = new Drumset(*smDrumset);
427                   }
428             }
429       else if (tag == "Drum") {
430             // if we see on of this tags, a custom drumset will
431             // be created
432             if (!_drumset)
433                   _drumset = new Drumset(*smDrumset);
434             if (!(*customDrumset)) {
435                   const_cast<Drumset*>(_drumset)->clear();
436                   *customDrumset = true;
437                   }
438             const_cast<Drumset*>(_drumset)->load(e);
439             }
440       // support tag "Tablature" for a while for compatibility with existent 2.0 scores
441       else if (tag == "Tablature" || tag == "StringData")
442             _stringData.read(e);
443       else if (tag == "MidiAction") {
444             NamedEventList a;
445             a.read(e);
446             _midiActions.append(a);
447             }
448       else if (tag == "Articulation") {
449             MidiArticulation a;
450             a.read(e);
451             _articulation.append(a);
452             }
453       else if (tag == "Channel" || tag == "channel") {
454             Channel* a = new Channel;
455             a->read(e, part);
456             _channel.append(a);
457             }
458       else if (tag == "clef") {           // sets both transposing and concert clef
459             int idx = e.intAttribute("staff", 1) - 1;
460             QString val(e.readElementText());
461             ClefType ct = Clef::clefType(val);
462             setClefType(idx, ClefTypeList(ct, ct));
463             }
464       else if (tag == "concertClef") {
465             int idx = e.intAttribute("staff", 1) - 1;
466             QString val(e.readElementText());
467             setClefType(idx, ClefTypeList(Clef::clefType(val), clefType(idx)._transposingClef));
468             }
469       else if (tag == "transposingClef") {
470             int idx = e.intAttribute("staff", 1) - 1;
471             QString val(e.readElementText());
472             setClefType(idx, ClefTypeList(clefType(idx)._concertClef, Clef::clefType(val)));
473             }
474       else
475             return false;
476 
477       return true;
478       }
479 
480 //---------------------------------------------------------
481 //   action
482 //---------------------------------------------------------
483 
midiAction(const QString & s,int channelIdx) const484 NamedEventList* Instrument::midiAction(const QString& s, int channelIdx) const
485       {
486       // first look in channel list
487 
488       foreach(const NamedEventList& a, _channel[channelIdx]->midiActions) {
489             if (s == a.name)
490                   return const_cast<NamedEventList*>(&a);
491             }
492 
493       foreach(const NamedEventList& a, _midiActions) {
494             if (s == a.name)
495                   return const_cast<NamedEventList*>(&a);
496             }
497       return 0;
498       }
499 
500 //---------------------------------------------------------
501 //   Channel
502 //---------------------------------------------------------
503 
Channel()504 Channel::Channel()
505       {
506       for(int i = 0; i < int(A::INIT_COUNT); ++i)
507             _init.push_back(MidiCoreEvent());
508       _synti    = "Fluid";     // default synthesizer
509       _channel  = -1;
510       _program  = -1;
511       _bank     = 0;
512       _volume   = defaultVolume;
513       _pan      = 64; // actually 63.5 for center
514       _chorus   = 0;
515       _reverb   = 0;
516       _color = DEFAULT_COLOR;
517 
518       _mute     = false;
519       _solo     = false;
520       _soloMute = false;
521 
522 //      qDebug("construct Channel ");
523       }
524 
525 //---------------------------------------------------------
526 //   initList
527 //---------------------------------------------------------
528 
initList() const529 std::vector<MidiCoreEvent>& Channel::initList() const
530       {
531       if (_mustUpdateInit) {
532             updateInitList();
533             _mustUpdateInit = false;
534             }
535       return _init;
536       }
537 
538 //---------------------------------------------------------
539 //   setVolume
540 //---------------------------------------------------------
541 
setVolume(char value)542 void Channel::setVolume(char value)
543       {
544       if (_volume != value) {
545             _volume = value;
546             firePropertyChanged(Prop::VOLUME);
547             }
548       _mustUpdateInit = true;
549       }
550 
551 //---------------------------------------------------------
552 //   setPan
553 //---------------------------------------------------------
554 
setPan(char value)555 void Channel::setPan(char value)
556       {
557       if (_pan != value) {
558             _pan = value;
559             firePropertyChanged(Prop::PAN);
560             }
561       _mustUpdateInit = true;
562       }
563 
564 //---------------------------------------------------------
565 //   setChorus
566 //---------------------------------------------------------
567 
setChorus(char value)568 void Channel::setChorus(char value)
569       {
570       if (_chorus != value) {
571             _chorus = value;
572             firePropertyChanged(Prop::CHORUS);
573             }
574       _mustUpdateInit = true;
575       }
576 
577 //---------------------------------------------------------
578 //   setReverb
579 //---------------------------------------------------------
580 
setReverb(char value)581 void Channel::setReverb(char value)
582       {
583       if (_reverb != value) {
584             _reverb = value;
585             firePropertyChanged(Prop::REVERB);
586             }
587       _mustUpdateInit = true;
588       }
589 
590 //---------------------------------------------------------
591 //   setName
592 //---------------------------------------------------------
593 
setName(const QString & value)594 void Channel::setName(const QString& value)
595       {
596       if (_name != value) {
597             _name = value;
598             firePropertyChanged(Prop::NAME);
599             }
600       }
601 
602 //---------------------------------------------------------
603 //   setDescr
604 //---------------------------------------------------------
605 
setDescr(const QString & value)606 void Channel::setDescr(const QString& value)
607       {
608       if (_descr != value) {
609             _descr = value;
610             firePropertyChanged(Prop::DESCR);
611             }
612       }
613 
614 //---------------------------------------------------------
615 //   setSynti
616 //---------------------------------------------------------
617 
setSynti(const QString & value)618 void Channel::setSynti(const QString& value)
619       {
620       if (_synti != value) {
621             _synti = value;
622             firePropertyChanged(Prop::SYNTI);
623             }
624       }
625 
626 //---------------------------------------------------------
627 //   setColor
628 //---------------------------------------------------------
629 
setColor(int value)630 void Channel::setColor(int value)
631       {
632       if (_color != value) {
633             _color = value;
634             firePropertyChanged(Prop::COLOR);
635             }
636       }
637 
638 //---------------------------------------------------------
639 //   setProgram
640 //---------------------------------------------------------
641 
setProgram(int value)642 void Channel::setProgram(int value)
643       {
644       if (_program != value) {
645             _program = value;
646             firePropertyChanged(Prop::PROGRAM);
647             }
648       _mustUpdateInit = true;
649       }
650 
651 //---------------------------------------------------------
652 //   setBank
653 //---------------------------------------------------------
654 
setBank(int value)655 void Channel::setBank(int value)
656       {
657       if (_bank != value) {
658             _bank = value;
659             firePropertyChanged(Prop::BANK);
660             }
661       _mustUpdateInit = true;
662       }
663 
664 //---------------------------------------------------------
665 //   setChannel
666 //---------------------------------------------------------
667 
setChannel(int value)668 void Channel::setChannel(int value)
669       {
670       if (_channel != value) {
671             _channel = value;
672             firePropertyChanged(Prop::CHANNEL);
673             }
674       }
675 
676 //---------------------------------------------------------
677 //   setSoloMute
678 //---------------------------------------------------------
679 
setSoloMute(bool value)680 void Channel::setSoloMute(bool value)
681       {
682       if (_soloMute != value) {
683             _soloMute = value;
684             firePropertyChanged(Prop::SOLOMUTE);
685             }
686       }
687 
688 //---------------------------------------------------------
689 //   setMute
690 //---------------------------------------------------------
691 
setMute(bool value)692 void Channel::setMute(bool value)
693       {
694       if (_mute != value) {
695             _mute = value;
696             firePropertyChanged(Prop::MUTE);
697             }
698       }
699 
700 //---------------------------------------------------------
701 //   setSolo
702 //---------------------------------------------------------
703 
setSolo(bool value)704 void Channel::setSolo(bool value)
705       {
706       if (_solo != value) {
707             _solo = value;
708             firePropertyChanged(Prop::SOLO);
709             }
710       }
711 
712 //---------------------------------------------------------
713 //   setUserBankController
714 //---------------------------------------------------------
715 
setUserBankController(bool val)716 void Channel::setUserBankController(bool val)
717       {
718       if (_userBankController != val) {
719             _userBankController = val;
720             firePropertyChanged(Prop::USER_BANK_CONTROL);
721             }
722       }
723 
724 //---------------------------------------------------------
725 //   write
726 //---------------------------------------------------------
727 
write(XmlWriter & xml,const Part * part) const728 void Channel::write(XmlWriter& xml, const Part* part) const
729       {
730       if (_name.isEmpty() || _name == DEFAULT_NAME)
731             xml.stag("Channel");
732       else
733             xml.stag(QString("Channel name=\"%1\"").arg(_name));
734       if (!_descr.isEmpty())
735             xml.tag("descr", _descr);
736       if (_color != DEFAULT_COLOR)
737             xml.tag("color", _color);
738 
739       for (const MidiCoreEvent& e : initList()) {
740             if (e.type() == ME_INVALID)
741                   continue;
742             if (e.type() == ME_CONTROLLER) {
743                   // Don't write bank if automatically switched, but always write if switched by the user
744                   if (e.dataA() == CTRL_HBANK && e.dataB() == 0 && !_userBankController)
745                         continue;
746                   if (e.dataA() == CTRL_LBANK && e.dataB() == 0 && !_userBankController)
747                         continue;
748                   if (e.dataA() == CTRL_VOLUME && e.dataB() == 100)
749                         continue;
750                   if (e.dataA() == CTRL_PANPOT && e.dataB() == 64)
751                         continue;
752                   if (e.dataA() == CTRL_REVERB_SEND && e.dataB() == 0)
753                         continue;
754                   if (e.dataA() == CTRL_CHORUS_SEND && e.dataB() == 0)
755                         continue;
756                   }
757 
758             e.write(xml);
759             }
760       if (!MScore::testMode)
761             // xml.tag("synti", ::synti->name(synti));
762             xml.tag("synti", _synti);
763       if (_mute)
764             xml.tag("mute", _mute);
765       if (_solo)
766             xml.tag("solo", _solo);
767 
768       if (part && part->masterScore()->exportMidiMapping() && part->score() == part->masterScore()) {
769             xml.tag("midiPort",    part->masterScore()->midiMapping(_channel)->port());
770             xml.tag("midiChannel", part->masterScore()->midiMapping(_channel)->channel());
771             }
772       for (const NamedEventList& a : midiActions)
773             a.write(xml, "MidiAction");
774       for (const MidiArticulation& a : articulation)
775             a.write(xml);
776       xml.etag();
777       }
778 
779 //---------------------------------------------------------
780 //   read
781 //---------------------------------------------------------
782 
read(XmlReader & e,Part * part)783 void Channel::read(XmlReader& e, Part* part)
784       {
785       // synti = 0;
786       _name = e.attribute("name");
787       if (_name == "")
788             _name = DEFAULT_NAME;
789 
790       int midiPort = -1;
791       int midiChannel = -1;
792 
793       while (e.readNextStartElement()) {
794             const QStringRef& tag(e.name());
795             if (tag == "program") {
796                   _program = e.intAttribute("value", -1);
797                   if (_program == -1)
798                         _program = e.readInt();
799                   else
800                         e.readNext();
801                   }
802             else if (tag == "controller") {
803                   int value = e.intAttribute("value", 0);
804                   int ctrl  = e.intAttribute("ctrl", 0);
805                   switch (ctrl) {
806                         case CTRL_HBANK:
807                               _bank = (value << 7) + (_bank & 0x7f);
808                               _userBankController = true;
809                               break;
810                         case CTRL_LBANK:
811                               _bank = (_bank & ~0x7f) + (value & 0x7f);
812                               _userBankController = true;
813                               break;
814                         case CTRL_VOLUME:
815                               _volume = value;
816                               break;
817                         case CTRL_PANPOT:
818                               _pan = value;
819                               break;
820                         case CTRL_CHORUS_SEND:
821                               _chorus = value;
822                               break;
823                         case CTRL_REVERB_SEND:
824                               _reverb = value;
825                               break;
826                         default:
827                               {
828                               Event ev(ME_CONTROLLER);
829                               ev.setOntime(-1);
830                               ev.setChannel(0);
831                               ev.setDataA(ctrl);
832                               ev.setDataB(value);
833                               _init.push_back(ev);
834                               }
835                               break;
836                         }
837                   e.readNext();
838                   }
839             else if (tag == "Articulation") {
840                   MidiArticulation a;
841                   a.read(e);
842                   articulation.append(a);
843                   }
844             else if (tag == "MidiAction") {
845                   NamedEventList a;
846                   a.read(e);
847                   midiActions.append(a);
848                   }
849             else if (tag == "synti")
850                   _synti = e.readElementText();
851             else if (tag == "descr")
852                   _descr = e.readElementText();
853             else if (tag == "color")
854                   _color = e.readInt();
855             else if (tag == "mute")
856                   _mute = e.readInt();
857             else if (tag == "solo")
858                   _solo = e.readInt();
859             else if (tag == "midiPort") {
860                   midiPort = e.readInt();
861                   }
862             else if (tag == "midiChannel") {
863                   midiChannel = e.readInt();
864                   }
865             else
866                   e.unknown();
867             }
868       if (128 == _bank && "zerberus" == _synti.toLower())
869             _bank = 0;
870 
871       _mustUpdateInit = true;
872 
873       if ((midiPort != -1 || midiChannel != -1) && part && part->score()->isMaster())
874             part->masterScore()->addMidiMapping(this, part, midiPort, midiChannel);
875       }
876 
877 //---------------------------------------------------------
878 //   switchExpressive
879 //    Switches channel from non-expressive to expressive patch or vice versa
880 //    This works only with MuseScore General soundfont
881 //---------------------------------------------------------
882 
switchExpressive(Synthesizer * synth,bool expressive,bool force)883 void Channel::switchExpressive(Synthesizer* synth, bool expressive, bool force /* = false */)
884       {
885       if ((_userBankController && !force) || !synth)
886             return;
887 
888       // Don't try to switch if we already have done so
889       if (expressive == _switchedToExpressive)
890             return;
891 
892       // Check that we're actually changing the MuseScore General soundfont
893       const auto fontsInfo = synth->soundFontsInfo();
894       if (fontsInfo.empty())
895             return;
896       const auto& info = fontsInfo.front();
897       if (!info.fontName.contains("MuseScore_General", Qt::CaseInsensitive)) {
898             qDebug().nospace() << "Soundfont '" << info.fontName << "' is not MuseScore General, cannot update expressive";
899             return;
900             }
901 
902       // Work out where the new expressive patch will be
903       // All expressive instruments are +1 bank higher than the
904       // normal counterparts, except on bank 0, where they are placed on bank 17
905       // and on bank 8, which uses bank 18 instead.
906       int searchBankNum;
907       int newBankNum;
908       if (expressive) {
909             int relativeBank = bank() % 129;
910             if (relativeBank == 0)
911                   newBankNum = 17;
912             else if (relativeBank == 8)
913                   newBankNum = 18;
914             else
915                   newBankNum = relativeBank + 1;
916             _switchedToExpressive = true;
917             }
918       else {
919             int relativeBank = bank() % 129;
920             if (relativeBank == 17)
921                   newBankNum = 0;
922             else if (relativeBank == 18)
923                   newBankNum = 8;
924             else
925                   newBankNum = relativeBank - 1;
926             _switchedToExpressive = false;
927             }
928 
929       // Floor bank num to multiple of 129 and add new num to get bank num of new patch
930       searchBankNum = (bank() / 129) * 129 + newBankNum;
931       const auto& pl = synth->getPatchInfo();
932       for (const MidiPatch* p : pl) {
933             if (p->synti == "Fluid") {
934                   if (searchBankNum == p->bank && program() == p->prog) {
935                         setBank(p->bank);
936                         return;
937                         }
938                   }
939             }
940       }
941 
942 //---------------------------------------------------------
943 //   updateInitList
944 //---------------------------------------------------------
945 
updateInitList() const946 void Channel::updateInitList() const
947       {
948       MidiCoreEvent e;
949       if (_program != -1) {
950             e.setType(ME_CONTROLLER);
951             e.setDataA(CTRL_PROGRAM);
952             e.setDataB(_program);
953             _init[int(A::PROGRAM)] = e;
954             }
955 
956       e.setData(ME_CONTROLLER, CTRL_HBANK, (_bank >> 7) & 0x7f);
957       _init[int(A::HBANK)] = e;
958 
959       e.setData(ME_CONTROLLER, CTRL_LBANK, _bank & 0x7f);
960       _init[int(A::LBANK)] = e;
961 
962       e.setData(ME_CONTROLLER, CTRL_VOLUME, volume());
963       _init[int(A::VOLUME)] = e;
964 
965       e.setData(ME_CONTROLLER, CTRL_PANPOT, pan());
966       _init[int(A::PAN)] = e;
967 
968       e.setData(ME_CONTROLLER, CTRL_CHORUS_SEND, chorus());
969       _init[int(A::CHORUS)] = e;
970 
971       e.setData(ME_CONTROLLER, CTRL_REVERB_SEND, reverb());
972       _init[int(A::REVERB)] = e;
973 
974       }
975 
976 //---------------------------------------------------------
977 //   addListener
978 //---------------------------------------------------------
979 
addListener(ChannelListener * l)980 void Channel::addListener(ChannelListener* l)
981       {
982       _notifier.addListener(l);
983       }
984 
985 //---------------------------------------------------------
986 //   removeListener
987 //---------------------------------------------------------
988 
removeListener(ChannelListener * l)989 void Channel::removeListener(ChannelListener* l)
990       {
991       _notifier.removeListener(l);
992       }
993 
994 //---------------------------------------------------------
995 //   PartChannelSettingsLink
996 //---------------------------------------------------------
997 
PartChannelSettingsLink(Channel * main,Channel * bound,bool excerpt)998 PartChannelSettingsLink::PartChannelSettingsLink(Channel* main, Channel* bound, bool excerpt)
999    : _main(main), _bound(bound), _excerpt(excerpt)
1000       {
1001       if (excerpt) {
1002             for (Channel::Prop p : excerptProperties)
1003                   applyProperty(p, /* from */ bound, /* to */ main);
1004             }
1005       // Maybe it would be good to assign common properties if the link
1006       // is constructed in non-excerpt mode. But it is not currently
1007       // necessary as playback channels are currently recreated on each
1008       // MIDI remapping.
1009 
1010       main->addListener(this);
1011       }
1012 
1013 //---------------------------------------------------------
1014 //   PartChannelSettingsLink
1015 //---------------------------------------------------------
1016 
PartChannelSettingsLink(PartChannelSettingsLink && other)1017 PartChannelSettingsLink::PartChannelSettingsLink(PartChannelSettingsLink&& other)
1018    : ChannelListener(), // swap() will set the notifier instead
1019    _main(nullptr), _bound(nullptr), _excerpt(false)
1020       {
1021       swap(*this, other);
1022       }
1023 
1024 //---------------------------------------------------------
1025 //   PartChannelSettingsLink::operator=
1026 //---------------------------------------------------------
1027 
operator =(PartChannelSettingsLink && other)1028 PartChannelSettingsLink& PartChannelSettingsLink::operator=(PartChannelSettingsLink&& other)
1029       {
1030       if (this != &other)
1031             swap(*this, other);
1032       return *this;
1033       }
1034 
1035 //---------------------------------------------------------
1036 //   swap
1037 //---------------------------------------------------------
1038 
swap(PartChannelSettingsLink & l1,PartChannelSettingsLink & l2)1039 void swap(PartChannelSettingsLink& l1, PartChannelSettingsLink& l2)
1040       {
1041       Ms::swap(static_cast<ChannelListener&>(l1), static_cast<ChannelListener&>(l2));
1042       using std::swap;
1043       swap(l1._main, l2._main);
1044       swap(l1._bound, l2._bound);
1045       swap(l1._excerpt, l2._excerpt);
1046       }
1047 
1048 //---------------------------------------------------------
1049 //   PartChannelSettingsLink::applyProperty
1050 //---------------------------------------------------------
1051 
applyProperty(Channel::Prop p,const Channel * from,Channel * to)1052 void PartChannelSettingsLink::applyProperty(Channel::Prop p, const Channel* from, Channel* to)
1053       {
1054       switch (p) {
1055             case Channel::Prop::VOLUME:
1056                   to->setVolume(from->volume());
1057                   break;
1058             case Channel::Prop::PAN:
1059                   to->setPan(from->pan());
1060                   break;
1061             case Channel::Prop::CHORUS:
1062                   to->setChorus(from->chorus());
1063                   break;
1064             case Channel::Prop::REVERB:
1065                   to->setReverb(from->reverb());
1066                   break;
1067             case Channel::Prop::NAME:
1068                   to->setName(from->name());
1069                   break;
1070             case Channel::Prop::DESCR:
1071                   to->setDescr(from->descr());
1072                   break;
1073             case Channel::Prop::PROGRAM:
1074                   to->setProgram(from->program());
1075                   break;
1076             case Channel::Prop::BANK:
1077                   to->setBank(from->bank());
1078                   break;
1079             case Channel::Prop::COLOR:
1080                   to->setColor(from->color());
1081                   break;
1082             case Channel::Prop::SOLOMUTE:
1083                   to->setSoloMute(from->soloMute());
1084                   break;
1085             case Channel::Prop::SOLO:
1086                   to->setSolo(from->solo());
1087                   break;
1088             case Channel::Prop::MUTE:
1089                   to->setMute(from->mute());
1090                   break;
1091             case Channel::Prop::SYNTI:
1092                   to->setSynti(from->synti());
1093                   break;
1094             case Channel::Prop::CHANNEL:
1095                   to->setChannel(from->channel());
1096                   break;
1097             case Channel::Prop::USER_BANK_CONTROL:
1098                   to->setUserBankController(from->userBankController());
1099                   break;
1100             };
1101       }
1102 
1103 //---------------------------------------------------------
1104 //   PartChannelSettingsLink::propertyChanged
1105 //---------------------------------------------------------
1106 
propertyChanged(Channel::Prop p)1107 void PartChannelSettingsLink::propertyChanged(Channel::Prop p)
1108       {
1109       if (isExcerptProperty(p) == _excerpt)
1110             applyProperty(p, _main, _bound);
1111       }
1112 
1113 //---------------------------------------------------------
1114 //   channelIdx
1115 //---------------------------------------------------------
1116 
channelIdx(const QString & s) const1117 int Instrument::channelIdx(const QString& s) const
1118       {
1119       int idx = 0;
1120       for (const Channel* a : _channel) {
1121             if (a->name().isEmpty() && s == Channel::DEFAULT_NAME)
1122                   return idx;
1123             if (s == a->name())
1124                   return idx;
1125             ++idx;
1126             }
1127       return -1;
1128       }
1129 
1130 //---------------------------------------------------------
1131 //   write
1132 //---------------------------------------------------------
1133 
write(XmlWriter & xml) const1134 void MidiArticulation::write(XmlWriter& xml) const
1135       {
1136       if (name.isEmpty())
1137             xml.stag("Articulation");
1138       else
1139             xml.stag(QString("Articulation name=\"%1\"").arg(name));
1140       if (!descr.isEmpty())
1141             xml.tag("descr", descr);
1142       xml.tag("velocity", velocity);
1143       xml.tag("gateTime", gateTime);
1144       xml.etag();
1145       }
1146 
1147 //---------------------------------------------------------
1148 //   read
1149 //---------------------------------------------------------
1150 
read(XmlReader & e)1151 void MidiArticulation::read(XmlReader& e)
1152       {
1153       name = e.attribute("name");
1154       while (e.readNextStartElement()) {
1155             const QStringRef& tag(e.name());
1156             if (tag == "velocity") {
1157                   QString text(e.readElementText());
1158                   if (text.endsWith("%"))
1159                         text = text.left(text.size()-1);
1160                   velocity = text.toInt();
1161                   }
1162             else if (tag == "gateTime") {
1163                   QString text(e.readElementText());
1164                   if (text.endsWith("%"))
1165                         text = text.left(text.size()-1);
1166                   gateTime = text.toInt();
1167                   }
1168             else if (tag == "descr")
1169                   descr = e.readElementText();
1170             else
1171                   e.unknown();
1172             }
1173       }
1174 
1175 //---------------------------------------------------------
1176 //   updateVelocity
1177 //---------------------------------------------------------
1178 
updateVelocity(int * velocity,int,const QString & name)1179 void Instrument::updateVelocity(int* velocity, int /*channelIdx*/, const QString& name)
1180       {
1181       *velocity *= getVelocityMultiplier(name);
1182       }
1183 
1184 //---------------------------------------------------------
1185 //   updateVelocity
1186 //---------------------------------------------------------
1187 
getVelocityMultiplier(const QString & name)1188 qreal Instrument::getVelocityMultiplier(const QString& name)
1189       {
1190       for (const MidiArticulation& a : qAsConst(_articulation)) {
1191             if (a.name == name) {
1192                   return qreal(a.velocity) / 100;
1193                   }
1194             }
1195       return 1;
1196       }
1197 
1198 //---------------------------------------------------------
1199 //   updateGateTime
1200 //---------------------------------------------------------
1201 
updateGateTime(int * gateTime,int,const QString & name)1202 void Instrument::updateGateTime(int* gateTime, int /*channelIdx*/, const QString& name)
1203       {
1204       for (const MidiArticulation& a : qAsConst(_articulation)) {
1205             if (a.name == name) {
1206                   *gateTime = a.gateTime;
1207                   break;
1208                   }
1209             }
1210       }
1211 
1212 
1213 //---------------------------------------------------------
1214 //   updateGateTime
1215 //---------------------------------------------------------
1216 
switchExpressive(MasterScore * score,Synthesizer * synth,bool expressive,bool force)1217 void Instrument::switchExpressive(MasterScore* score, Synthesizer* synth, bool expressive, bool force /* = false */)
1218       {
1219       // Only switch to expressive where necessary
1220       if (!synth || (expressive && !singleNoteDynamics()))
1221             return;
1222 
1223       for (Channel* c : channel()) {
1224             c->switchExpressive(synth, expressive, force);
1225             if (score->playbackChannel(c))
1226                   score->playbackChannel(c)->switchExpressive(synth, expressive, force);
1227             }
1228       }
1229 
1230 //---------------------------------------------------------
1231 //   operator==
1232 //---------------------------------------------------------
1233 
operator ==(const Instrument & i) const1234 bool Instrument::operator==(const Instrument& i) const
1235       {
1236       int n = _longNames.size();
1237       if (i._longNames.size() != n)
1238             return false;
1239       for (int k = 0; k < n; ++k) {
1240             if (!(i._longNames[k] == _longNames[k]))
1241                   return false;
1242             }
1243       n = _shortNames.size();
1244       if (i._shortNames.size() != n)
1245             return false;
1246       for (int k = 0; k < n; ++k) {
1247             if (!(i._shortNames[k] == _shortNames[k].name()))
1248                   return false;
1249             }
1250       n = _channel.size();
1251       if (i._channel.size() != n)
1252             return false;
1253       for (int k = 0; k < n; ++k) {
1254             if (!(*i._channel[k] == *_channel[k]))
1255                   return false;
1256             }
1257 
1258       return i._minPitchA == _minPitchA
1259          &&  i._maxPitchA == _maxPitchA
1260          &&  i._minPitchP == _minPitchP
1261          &&  i._maxPitchP == _maxPitchP
1262          &&  i._useDrumset == _useDrumset
1263          &&  i._midiActions == _midiActions
1264          &&  i._articulation == _articulation
1265          &&  i._transpose.diatonic == _transpose.diatonic
1266          &&  i._transpose.chromatic == _transpose.chromatic
1267          &&  i._trackName == _trackName
1268          &&  *i.stringData() == *stringData()
1269          &&  i._singleNoteDynamics == _singleNoteDynamics;
1270       }
1271 
1272 //---------------------------------------------------------
1273 //   isDifferentInstrument
1274 ///   Checks if the passed instrument is a different instrument.
1275 ///   Does not compare channels.
1276 //---------------------------------------------------------
1277 
isDifferentInstrument(const Instrument & i) const1278 bool Instrument::isDifferentInstrument(const Instrument& i) const
1279       {
1280       int n = _longNames.size();
1281       if (i._longNames.size() != n)
1282             return true;
1283       for (int k = 0; k < n; ++k) {
1284             if (!(i._longNames[k] == _longNames[k]))
1285                   return true;
1286             }
1287       n = _shortNames.size();
1288       if (i._shortNames.size() != n)
1289             return true;
1290       for (int k = 0; k < n; ++k) {
1291             if (!(i._shortNames[k] == _shortNames[k].name()))
1292                   return true;
1293             }
1294 
1295       return i._minPitchA != _minPitchA
1296             || i._maxPitchA != _maxPitchA
1297             || i._minPitchP != _minPitchP
1298             || i._maxPitchP != _maxPitchP
1299             || i._useDrumset != _useDrumset
1300             || i._midiActions != _midiActions
1301             || i._articulation != _articulation
1302             || i._transpose.diatonic != _transpose.diatonic
1303             || i._transpose.chromatic != _transpose.chromatic
1304             || i._trackName != _trackName
1305             || !(*i.stringData() == *stringData())
1306             || i._singleNoteDynamics != _singleNoteDynamics;
1307       }
1308 
1309 //---------------------------------------------------------
1310 //   operator==
1311 //---------------------------------------------------------
1312 
operator ==(const StaffName & i) const1313 bool StaffName::operator==(const StaffName& i) const
1314       {
1315       return (i._pos == _pos) && (i._name == _name);
1316       }
1317 
toString() const1318 QString StaffName::toString() const
1319       {
1320       return _name;
1321       }
1322 
1323 //---------------------------------------------------------
1324 //   setUseDrumset
1325 //---------------------------------------------------------
1326 
setUseDrumset(bool val)1327 void Instrument::setUseDrumset(bool val)
1328       {
1329       _useDrumset = val;
1330       if (val && !_drumset)
1331             _drumset = new Drumset(*smDrumset);
1332       }
1333 
1334 //---------------------------------------------------------
1335 //   setDrumset
1336 //---------------------------------------------------------
1337 
setDrumset(const Drumset * ds)1338 void Instrument::setDrumset(const Drumset* ds)
1339       {
1340       delete _drumset;
1341       if (ds) {
1342             _useDrumset = true;
1343             _drumset = new Drumset(*ds);
1344             }
1345       else {
1346             _useDrumset = false;
1347             _drumset = 0;
1348             }
1349       }
1350 
1351 //---------------------------------------------------------
1352 //   setLongName
1353 //    f is in richtext format
1354 //---------------------------------------------------------
1355 
setLongName(const QString & f)1356 void Instrument::setLongName(const QString& f)
1357       {
1358       _longNames.clear();
1359       if (f.length() > 0)
1360             _longNames.append(StaffName(f, 0));
1361       }
1362 
1363 //---------------------------------------------------------
1364 //   setShortName
1365 //    f is in richtext format
1366 //---------------------------------------------------------
1367 
setShortName(const QString & f)1368 void Instrument::setShortName(const QString& f)
1369       {
1370       _shortNames.clear();
1371       if (f.length() > 0)
1372             _shortNames.append(StaffName(f, 0));
1373       }
1374 
1375 //---------------------------------------------------------
1376 //   addLongName
1377 //---------------------------------------------------------
1378 
addLongName(const StaffName & f)1379 void Instrument::addLongName(const StaffName& f)
1380       {
1381       _longNames.append(f);
1382       }
1383 
1384 //---------------------------------------------------------
1385 //   addShortName
1386 //---------------------------------------------------------
1387 
addShortName(const StaffName & f)1388 void Instrument::addShortName(const StaffName& f)
1389       {
1390       _shortNames.append(f);
1391       }
1392 
1393 //---------------------------------------------------------
1394 //   clefType
1395 //---------------------------------------------------------
1396 
clefType(int staffIdx) const1397 ClefTypeList Instrument::clefType(int staffIdx) const
1398       {
1399       if (staffIdx >= _clefType.size()) {
1400             if (_clefType.empty())
1401                   return ClefTypeList(staffIdx == 1 ? ClefType::F : ClefType::G);
1402             return _clefType[0];
1403             }
1404       return _clefType[staffIdx];
1405       }
1406 
1407 //---------------------------------------------------------
1408 //   setClefType
1409 //---------------------------------------------------------
1410 
setClefType(int staffIdx,const ClefTypeList & c)1411 void Instrument::setClefType(int staffIdx, const ClefTypeList& c)
1412       {
1413       while (_clefType.size() <= staffIdx)
1414             _clefType.append(ClefTypeList());
1415       _clefType[staffIdx] = c;
1416       }
1417 
1418 //---------------------------------------------------------
1419 //   minPitchP
1420 //---------------------------------------------------------
1421 
minPitchP() const1422 int Instrument::minPitchP() const
1423       {
1424       return _minPitchP;
1425       }
1426 
1427 //---------------------------------------------------------
1428 //   maxPitchP
1429 //---------------------------------------------------------
1430 
maxPitchP() const1431 int Instrument::maxPitchP() const
1432       {
1433       return _maxPitchP;
1434       }
1435 
1436 //---------------------------------------------------------
1437 //   minPitchA
1438 //---------------------------------------------------------
1439 
minPitchA() const1440 int Instrument::minPitchA() const
1441       {
1442       return _minPitchA;
1443       }
1444 
1445 //---------------------------------------------------------
1446 //   maxPitchA
1447 //---------------------------------------------------------
1448 
maxPitchA() const1449 int Instrument::maxPitchA() const
1450       {
1451       return _maxPitchA;
1452       }
1453 
1454 //---------------------------------------------------------
1455 //   instrumentId
1456 //---------------------------------------------------------
1457 
instrumentId() const1458 QString Instrument::instrumentId() const
1459       {
1460       return _instrumentId;
1461       }
1462 
1463 //---------------------------------------------------------
1464 //   instrument
1465 //---------------------------------------------------------
1466 
instrument(int tick) const1467 const Instrument* InstrumentList::instrument(int tick) const
1468       {
1469       if (empty())
1470             return &defaultInstrument;
1471       auto i = upper_bound(tick);
1472       if (i == begin())
1473             return &defaultInstrument;
1474       --i;
1475       return i->second;
1476       }
1477 
1478 //---------------------------------------------------------
1479 //   instrument
1480 //---------------------------------------------------------
1481 
instrument(int tick)1482 Instrument* InstrumentList::instrument(int tick)
1483       {
1484       if (empty())
1485             return &defaultInstrument;
1486       auto i = upper_bound(tick);
1487       if (i == begin())
1488             return &defaultInstrument;
1489       --i;
1490       return i->second;
1491       }
1492 
1493 //---------------------------------------------------------
1494 //   setInstrument
1495 //---------------------------------------------------------
1496 
setInstrument(Instrument * instr,int tick)1497 void InstrumentList::setInstrument(Instrument* instr, int tick)
1498       {
1499       if (!insert({tick, instr}).second)
1500             (*this)[tick] = instr;
1501       }
1502 
1503 //---------------------------------------------------------
1504 //   longName
1505 //---------------------------------------------------------
1506 
longNames() const1507 const QList<StaffName>& Instrument::longNames() const
1508       {
1509       return _longNames;
1510       }
1511 
1512 //---------------------------------------------------------
1513 //   shortName
1514 //---------------------------------------------------------
1515 
shortNames() const1516 const QList<StaffName>& Instrument::shortNames() const
1517       {
1518       return _shortNames;
1519       }
1520 
1521 //---------------------------------------------------------
1522 //   longName
1523 //---------------------------------------------------------
1524 
longNames()1525 QList<StaffName>& Instrument::longNames()
1526       {
1527       return _longNames;
1528       }
1529 
1530 //---------------------------------------------------------
1531 //   shortName
1532 //---------------------------------------------------------
1533 
shortNames()1534 QList<StaffName>& Instrument::shortNames()
1535       {
1536       return _shortNames;
1537       }
1538 
1539 //---------------------------------------------------------
1540 //   trackName
1541 //---------------------------------------------------------
1542 
trackName() const1543 QString Instrument::trackName() const
1544       {
1545       return _trackName;
1546       }
1547 
setTrackName(const QString & s)1548 void Instrument::setTrackName(const QString& s)
1549       {
1550       _trackName = s;
1551       }
1552 
1553 //---------------------------------------------------------
1554 //   fromTemplate
1555 //---------------------------------------------------------
1556 
fromTemplate(const InstrumentTemplate * t)1557 Instrument Instrument::fromTemplate(const InstrumentTemplate* t)
1558       {
1559       Instrument instr(t->id);
1560       instr.setAmateurPitchRange(t->minPitchA, t->maxPitchA);
1561       instr.setProfessionalPitchRange(t->minPitchP, t->maxPitchP);
1562       for (const StaffName &sn : t->longNames)
1563             instr.addLongName(StaffName(sn.name(), sn.pos()));
1564       for (const StaffName &sn : t->shortNames)
1565             instr.addShortName(StaffName(sn.name(), sn.pos()));
1566       instr.setTrackName(t->trackName);
1567       instr.setTranspose(t->transpose);
1568       instr.setInstrumentId(t->musicXMLid);
1569       if (t->useDrumset)
1570             instr.setDrumset(t->drumset ? t->drumset : smDrumset);
1571       for (int i = 0; i < t->nstaves(); ++i)
1572             instr.setClefType(i, t->clefTypes[i]);
1573       instr.setMidiActions(t->midiActions);
1574       instr.setArticulation(t->articulation);
1575       instr._channel.clear();
1576       for (const Channel& c : t->channel)
1577             instr._channel.append(new Channel(c));
1578       instr.setStringData(t->stringData);
1579       instr.setSingleNoteDynamics(t->singleNoteDynamics);
1580       return instr;
1581       }
1582 
1583 //---------------------------------------------------------
1584 //  updateInstrumentId
1585 //---------------------------------------------------------
1586 
updateInstrumentId()1587 void Instrument::updateInstrumentId()
1588       {
1589       if (!_id.isEmpty() || _instrumentId.isEmpty())
1590             return;
1591 
1592       // When reading a score create with pre-3.6, instruments doesn't
1593       // have an id define in the instrument. So try to find the instrumentId
1594       // based on MusicXMLid.
1595       // This requires a hack for instruments using MusicXMLid "strings.group"
1596       // because there are multiple instrument using this same id.
1597       // For these instruments, use the value of controller 32 of the "arco"
1598       // channel to find the correct instrument.
1599       const QString arco = QString("arco");
1600       const bool groupHack = instrumentId() == QString("strings.group");
1601       const int idxref = channelIdx(arco);
1602       const int val32ref = (idxref < 0) ? -1 : channel(idxref)->bank();
1603       QString fallback;
1604 
1605       for (InstrumentGroup* g : instrumentGroups) {
1606             for (InstrumentTemplate* it : g->instrumentTemplates) {
1607                   if (it->musicXMLid == instrumentId()) {
1608                         if (groupHack) {
1609                               if (fallback.isEmpty())
1610                                     // Instrument "Strings" doesn't have bank defined so
1611                                     // if no "strings.group" instrument with requested bank
1612                                     // is found, assume "Strings".
1613                                     fallback = it->id;
1614                               for (const Channel& chan : it->channel) {
1615                                     if ((chan.name() == arco) && (chan.bank() == val32ref)) {
1616                                           _id = it->id;
1617                                           return;
1618                                           }
1619                                     }
1620                               }
1621                         else {
1622                               _id = it->id;
1623                               return;
1624                               }
1625                         }
1626                   }
1627             }
1628 
1629       _id = fallback.isEmpty() ? QString("piano") : fallback;
1630       }
1631 
1632 //---------------------------------------------------------
1633 //   Instrument::playbackChannel
1634 //---------------------------------------------------------
1635 
playbackChannel(int idx,const MasterScore * score) const1636 const Channel* Instrument::playbackChannel(int idx, const MasterScore* score) const
1637       {
1638       return score->playbackChannel(channel(idx));
1639       }
1640 
1641 
1642 //---------------------------------------------------------
1643 //   Instrument::playbackChannel
1644 //---------------------------------------------------------
1645 
playbackChannel(int idx,MasterScore * score)1646 Channel* Instrument::playbackChannel(int idx, MasterScore* score)
1647       {
1648       return score->playbackChannel(channel(idx));
1649       }
1650 
1651 //---------------------------------------------------------
1652 //   getSingleNoteDynamicsFromTemplate
1653 //---------------------------------------------------------
1654 
getSingleNoteDynamicsFromTemplate() const1655 bool Instrument::getSingleNoteDynamicsFromTemplate() const
1656       {
1657       QString templateName = trackName().toLower().replace(" ", "-").replace("♭", "b");
1658       InstrumentTemplate* tp = searchTemplate(templateName);
1659       if (tp)
1660             return tp->singleNoteDynamics;
1661       return true;
1662       }
1663 
1664 //---------------------------------------------------------
1665 //   setSingleNoteDynamicsFromTemplate
1666 //---------------------------------------------------------
1667 
setSingleNoteDynamicsFromTemplate()1668 void Instrument::setSingleNoteDynamicsFromTemplate()
1669       {
1670       setSingleNoteDynamics(getSingleNoteDynamicsFromTemplate());
1671       }
1672 
1673 //---------------------------------------------------------
1674 //   StaffNameList::write
1675 //---------------------------------------------------------
1676 
write(XmlWriter & xml,const char * name) const1677 void StaffNameList::write(XmlWriter& xml, const char* name) const
1678       {
1679       for (const StaffName& sn : *this)
1680             sn.write(xml, name);
1681       }
1682 
toStringList() const1683 QStringList StaffNameList::toStringList() const
1684       {
1685       QStringList result;
1686 
1687       for (const StaffName& name : *this)
1688             result << name.toString();
1689 
1690       return result;
1691       }
1692 }
1693 
1694