1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //
5 //  midnam.h
6 //  (C) Copyright 2019, 2020 Tim E. Real (terminator356 on users dot sourceforge dot net)
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //=========================================================
23 
24 #ifndef __MIDNAM_H__
25 #define __MIDNAM_H__
26 
27 #include <map>
28 #include <set>
29 #include <list>
30 #include <QString>
31 
32 #include "xml.h"
33 #include "mpevent.h"
34 #include "midi_controller.h"
35 
36 namespace MusECore {
37 
38 struct MidNamReferencesList;
39 
40 class MidiNamMIDICommands : public MPEventList
41 {
42   private:
43     bool _isPatchMIDICommands;
44     // If bank high or low control commands are detected,
45     //  these values are set to them. Otherwise they are
46     //  set at 'unknown' (default) 0xff.
47     int _bankH;
48     int _bankL;
49     bool _hasBankH;
50     bool _hasBankL;
51 
52   public:
MidiNamMIDICommands()53     MidiNamMIDICommands() :
54       _isPatchMIDICommands(false), _bankH(0xff), _bankL(0xff), _hasBankH(false), _hasBankL(false)  { }
isPatchMIDICommands()55     bool isPatchMIDICommands() const { return _isPatchMIDICommands; }
setIsPatchMIDICommands(bool v)56     void setIsPatchMIDICommands(bool v) { _isPatchMIDICommands = v; }
bankH()57     int bankH() const { return _bankH; }
bankL()58     int bankL() const { return _bankL; }
hasBankH()59     bool hasBankH() const { return _hasBankH; }
hasBankL()60     bool hasBankL() const { return _hasBankL; }
61     void write(int level, MusECore::Xml& xml) const;
62     bool read(
63       MusECore::Xml& xml,
64       bool includeSysEx = true,
65       int defaultPort = 0,
66       bool channelRequired = false,
67       int defaultChannel = 0);
68 };
69 
70 
71 //-------------------------------------------------------------------
72 
73 
74 class MidiNamAvailableChannel
75 {
76   private:
77     int _channel;
78     bool _available;
79 
80   public:
MidiNamAvailableChannel()81     MidiNamAvailableChannel() : _channel(0), _available(false) { }
MidiNamAvailableChannel(int channel,bool available)82     MidiNamAvailableChannel(int channel, bool available) : _channel(channel), _available(available) { }
channel()83     int channel() const { return _channel; }
available()84     bool available() const { return _available; }
setAvailable(bool available)85     void setAvailable(bool available) {
86         _available = available; }
87     bool operator<(const MidiNamAvailableChannel& n) const { return _channel < n._channel; }
88     void write(int level, MusECore::Xml& xml) const;
89     bool read(MusECore::Xml& xml);
90 };
91 
92 
93 //-------------------------------------------------------------------
94 
95 
96 class MidiNamAvailableForChannels : public std::map<int /* channel */, MidiNamAvailableChannel*, std::less<int>>
97 {
98   public:
MidiNamAvailableForChannels()99     MidiNamAvailableForChannels() { }
100     MidiNamAvailableForChannels(const MidiNamAvailableForChannels& m);
101     ~MidiNamAvailableForChannels();
102     bool add(MidiNamAvailableChannel* a);
103     void write(int level, MusECore::Xml& xml) const;
104     void read(MusECore::Xml& xml);
105 };
106 typedef MidiNamAvailableForChannels::iterator iMidiNamAvailableForChannels;
107 typedef MidiNamAvailableForChannels::const_iterator ciMidiNamAvailableForChannels;
108 typedef std::pair<int /* channel */, MidiNamAvailableChannel*> MidiNamAvailableForChannelsPair;
109 
110 
111 //-------------------------------------------------------------------
112 
113 
114 class MidNamChannelNameSet;
115 class MidiNamPatch;
116 class MidiNamPatchBankList;
117 class MidiNamChannelNameSetAssign
118 {
119   private:
120     int _channel;
121     QString _name;
122 
123     // Points to a reference.
124     MidNamChannelNameSet* _p_ref;
125 
126   public:
MidiNamChannelNameSetAssign()127     MidiNamChannelNameSetAssign() : _channel(0), _p_ref(nullptr) { }
MidiNamChannelNameSetAssign(int channel,const QString & nameSet)128     MidiNamChannelNameSetAssign(int channel, const QString& nameSet) :
129       _channel(channel), _name(nameSet), _p_ref(nullptr) { }
channel()130     int channel() const { return _channel; }
name()131     const QString& name() const { return _name; }
setName(const QString & nameSet)132     void setName(const QString& nameSet) {
133         _name = nameSet; }
134     // NOTE: Unlike the other referencing classes, this always returns the reference object and can be NULL.
objectOrRef()135     MidNamChannelNameSet* objectOrRef() { return  _p_ref; }
setObjectOrRef(MidNamChannelNameSet * l)136     void setObjectOrRef(MidNamChannelNameSet* l) { _p_ref = l; }
resetObjectOrRef()137     void resetObjectOrRef() { _p_ref = nullptr; }
138     bool gatherReferences(MidNamReferencesList* refs) const;
139     bool operator<(const MidiNamChannelNameSetAssign& n) const { return _channel < n._channel; }
140     void write(int level, MusECore::Xml& xml) const;
141     bool read(MusECore::Xml& xml);
142 
143     // Like find but if bank high or low are valid,
144     //  it searches for a match using them.
145     // Whereas find searches for an exact match.
146     const MidiNamPatch* findPatch(int channel, int patch) const;
147 
148     const MidiNamPatchBankList* getPatchBanks(int channel) const;
149 
150     // Find the list of controllers for a channel and/or patch.
151     // If channel is -1 or patch is don't care, it looks for defaults.
152     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
153 
154     bool getNoteSampleName(
155       bool drum, int channel, int patch, int note, QString* name) const;
156 };
157 
158 class MidiNamChannelNameSetAssignments : public std::map<int /* channel */, MidiNamChannelNameSetAssign*, std::less<int>>
159 {
160   private:
161     bool _hasChannelNameSetAssignments;
162 
163   public:
MidiNamChannelNameSetAssignments()164     MidiNamChannelNameSetAssignments() : _hasChannelNameSetAssignments(false) { }
165     MidiNamChannelNameSetAssignments(const MidiNamChannelNameSetAssignments& m);
166     ~MidiNamChannelNameSetAssignments();
hasChannelNameSetAssignments()167     bool hasChannelNameSetAssignments() const { return _hasChannelNameSetAssignments; }
168     bool add(MidiNamChannelNameSetAssign* a);
169     bool gatherReferences(MidNamReferencesList* refs) const;
170     void write(int level, MusECore::Xml& xml) const;
171     void read(MusECore::Xml& xml);
172 
173     // Like find but if bank high or low are valid,
174     //  it searches for a match using them.
175     // Whereas find searches for an exact match.
176     const MidiNamPatch* findPatch(int channel, int patch) const;
177 
178     const MidiNamPatchBankList* getPatchBanks(int channel) const;
179 
180     // Find the list of controllers for a channel and/or patch.
181     // If channel is -1 or patch is don't care, it looks for defaults.
182     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
183 
184     bool getNoteSampleName(
185       bool drum, int channel, int patch, int note, QString* name) const;
186 };
187 typedef MidiNamChannelNameSetAssignments::iterator iMidiNamChannelNameSetAssignments;
188 typedef MidiNamChannelNameSetAssignments::const_iterator ciMidiNamChannelNameSetAssignments;
189 typedef std::pair<int /* channel */, MidiNamChannelNameSetAssign*> MidiNamChannelNameSetAssignmentsPair;
190 
191 
192 //-------------------------------------------------------------------
193 
194 
195 class MidiNamNotes;
196 
197 class MidiNamNoteGroup : public std::set<int /* note number */>
198 {
199   private:
200     // Optional.
201     QString _name;
202 
203   public:
MidiNamNoteGroup()204     MidiNamNoteGroup() {}
MidiNamNoteGroup(const QString & name)205     MidiNamNoteGroup(const QString& name) : _name(name) { }
name()206     const QString& name() const { return _name; }
setName(const QString & name)207     void setName(const QString& name) { _name = name; }
208     bool operator<(const MidiNamNoteGroup& n) const { return _name < n._name; }
209     void write(int level, MusECore::Xml& xml, const MidiNamNotes* notes) const;
210     void read(MusECore::Xml& xml, MidiNamNotes* notes);
211 };
212 typedef MidiNamNoteGroup::iterator iMidiNamNoteGroup;
213 typedef MidiNamNoteGroup::const_iterator ciMidiNamNoteGroup;
214 typedef std::pair<iMidiNamNoteGroup, bool> MidiNamNoteGroupPair;
215 
216 // The note group name is optional, may be blank.
217 class MidiNamNoteGroups : public std::multimap<QString /* name */, MidiNamNoteGroup*, std::less<QString>>
218 {
219   public:
MidiNamNoteGroups()220     MidiNamNoteGroups() { }
221     MidiNamNoteGroups(const MidiNamNoteGroups& m);
222     ~MidiNamNoteGroups();
223     MidiNamNoteGroups& operator=(const MidiNamNoteGroups& m);
224     bool add(MidiNamNoteGroup* a);
225     void write(int level, MusECore::Xml& xml, const MidiNamNotes* notes) const;
226 };
227 typedef MidiNamNoteGroups::iterator iMidiNamNoteGroups;
228 typedef MidiNamNoteGroups::const_iterator ciMidiNamNoteGroups;
229 typedef std::pair<QString /* name */, MidiNamNoteGroup*> MidiNamNoteGroupsPair;
230 typedef std::pair<iMidiNamNoteGroups, iMidiNamNoteGroups> MidiNamNoteGroupsRange;
231 
232 
233 //-------------------------------------------------------------------
234 
235 
236 class MidiNamNote
237 {
238   private:
239     int _number;
240     QString _name;
241 
242   public:
MidiNamNote()243     MidiNamNote() : _number(0) { }
MidiNamNote(int number,const QString & name)244     MidiNamNote(int number, const QString& name) : _number(number), _name(name) { }
number()245     int number() const { return _number; }
name()246     const QString& name() const { return _name; }
setName(const QString & name)247     void setName(const QString& name) { _name = name; }
248     bool operator<(const MidiNamNote& n) const { return _number < n._number; }
249     void write(int level, MusECore::Xml& xml) const;
250     bool read(MusECore::Xml& xml);
251 };
252 
253 class MidiNamNotes : public std::map<int /* number */, MidiNamNote*, std::less<int>>
254 {
255   private:
256     MidiNamNoteGroups _noteGroups;
257 
258   public:
MidiNamNotes()259     MidiNamNotes() { }
260     MidiNamNotes(const MidiNamNotes& m);
261     ~MidiNamNotes();
noteGroups()262     MidiNamNoteGroups& noteGroups() { return _noteGroups; }
noteGroups()263     const MidiNamNoteGroups& noteGroups() const { return _noteGroups; }
isEmpty()264     bool isEmpty() const { return _noteGroups.empty() && empty(); }
265     bool add(MidiNamNote* a);
266     bool addNoteGroup(MidiNamNoteGroup* a);
267     void write(int level, MusECore::Xml& xml) const;
268 
269     bool getNoteSampleName(
270       bool drum, int channel, int patch, int note, QString* name) const;
271 };
272 typedef MidiNamNotes::iterator iMidiNamNotes;
273 typedef MidiNamNotes::const_iterator ciMidiNamNotes;
274 typedef std::pair<int /* number */, MidiNamNote*> MidiNamNotesPair;
275 typedef std::pair<iMidiNamNotes, bool> MidiNamNotesInsPair;
276 
277 
278 //-------------------------------------------------------------------
279 
280 
281 class MidNamNoteNameList
282 {
283   private:
284     QString _name;
285     MidiNamNotes _noteList;
286 
287     // Points to a reference.
288     MidNamNoteNameList* _p_ref;
289     bool _isReference;
290 
291     bool _hasNoteNameList;
292 
293   public:
MidNamNoteNameList()294     MidNamNoteNameList() : _p_ref(nullptr), _isReference(false), _hasNoteNameList(false) { }
MidNamNoteNameList(const QString & name)295     MidNamNoteNameList(const QString& name) :
296       _name(name), _p_ref(nullptr), _isReference(false), _hasNoteNameList(false) { }
hasNoteNameList()297     bool hasNoteNameList() const { return _hasNoteNameList; }
298     // Outside of these classes, always use this method to get the real list.
objectOrRef()299     const MidNamNoteNameList* objectOrRef() const { return (_isReference && _p_ref) ? _p_ref : this; }
objectOrRef()300     MidNamNoteNameList* objectOrRef() { return (_isReference && _p_ref) ? _p_ref : this; }
setObjectOrRef(MidNamNoteNameList * l)301     void setObjectOrRef(MidNamNoteNameList* l) { _p_ref = l; }
resetObjectOrRef()302     void resetObjectOrRef() { _p_ref = nullptr; }
303     bool gatherReferences(MidNamReferencesList* refs) const;
empty()304     bool empty() const { return _noteList.isEmpty(); }
noteList()305     const MidiNamNotes& noteList() const { return _noteList; }
name()306     const QString& name() const { return _name; }
setName(const QString & name)307     void setName(const QString& name) { _name = name; }
isReference()308     bool isReference() const { return _isReference; }
setIsReference(bool v)309     void setIsReference(bool v) { _isReference = v; }
310     bool operator<(const MidNamNoteNameList& n) const { return _name < n._name; }
311     void write(int level, MusECore::Xml& xml) const;
312     bool read(MusECore::Xml& xml);
313 
314     bool getNoteSampleName(
315       bool drum, int channel, int patch, int note, QString* name) const;
316 };
317 
318 
319 //-------------------------------------------------------
320 
321 
322 class MidiNamVal
323 {
324   private:
325     int _number;
326     QString _name;
327 
328   public:
MidiNamVal()329     MidiNamVal() : _number(0) { }
MidiNamVal(int number,const QString & name)330     MidiNamVal(int number, const QString& name) : _number(number), _name(name) { }
number()331     int number() const { return _number; }
name()332     const QString& name() const { return _name; }
setName(const QString & name)333     void setName(const QString& name) { _name = name; }
334     bool operator<(const MidiNamVal& n) const { return _number < n._number; }
335     void write(int level, MusECore::Xml& xml) const;
336     bool read(MusECore::Xml& xml);
337 };
338 
339 class MidiNamValNames : public std::map<int /* number */, MidiNamVal*, std::less<int>>
340 {
341   private:
342     QString _name;
343     // Points to a reference.
344     MidiNamValNames* _p_ref;
345     bool _isReference;
346 
347   public:
MidiNamValNames()348     MidiNamValNames() : _p_ref(nullptr), _isReference(false) {}
MidiNamValNames(const QString & name)349     MidiNamValNames(const QString& name) :
350       _name(name), _p_ref(nullptr), _isReference(false) { }
351     MidiNamValNames(const MidiNamValNames& m);
352     MidiNamValNames& operator=(const MidiNamValNames& m);
353     ~MidiNamValNames();
objectOrRef()354     MidiNamValNames* objectOrRef() { return (_isReference && _p_ref) ? _p_ref : this; }
setObjectOrRef(MidiNamValNames * l)355     void setObjectOrRef(MidiNamValNames* l) { _p_ref = l; }
resetObjectOrRef()356     void resetObjectOrRef() { _p_ref = nullptr; }
357     bool add(MidiNamVal* a);
358     bool gatherReferences(MidNamReferencesList* refs) const;
isReference()359     bool isReference() const { return _isReference; }
setIsReference(bool v)360     void setIsReference(bool v) { _isReference = v; }
name()361     const QString& name() const { return _name; }
setName(const QString & name)362     void setName(const QString& name) { _name = name; }
363     void write(int level, MusECore::Xml& xml) const;
364     void read(MusECore::Xml& xml);
365 };
366 typedef MidiNamValNames::iterator iMidiNamValNames;
367 typedef MidiNamValNames::const_iterator ciMidiNamValNames;
368 typedef std::pair<int /* number */, MidiNamVal*> MidiNamValNamesPair;
369 typedef std::pair<iMidiNamValNames, bool> MidiNamValNamesInsPair;
370 
371 
372 class MidiNamValues
373 {
374   private:
375     int _min;
376     int _max;
377     int _default;
378     int _units;
379     int _mapping;
380     MidiNamValNames _valueNames;
381 
382   public:
MidiNamValues()383     MidiNamValues() : _min(0), _max(127), _default(0), _units(0), _mapping(0) {}
MidiNamValues(int min,int max,int def,int units,int mapping)384     MidiNamValues(int min, int max, int def, int units, int mapping) :
385                 _min(min), _max(max), _default(def), _units(units),
386                 _mapping(mapping) {}
minVal()387     int minVal() const { return _min; }
setMinVal(int v)388     void setMinVal(int v) { _min = v; }
maxVal()389     int maxVal() const { return _max; }
setMaxVal(int v)390     void setMaxVal(int v) { _max = v; }
defaultVal()391     int defaultVal() const { return _default; }
setDefaultVal(int v)392     void setDefaultVal(int v) { _default = v; }
units()393     int units() const { return _units; }
setUnits(int v)394     void setUnits(int v) { _units = v; }
mapping()395     int mapping() const { return _mapping; }
setMapping(int v)396     void setMapping(int v) { _mapping = v; }
valueNames()397     MidiNamValNames& valueNames() { return _valueNames; }
empty()398     bool empty() const { return _valueNames.empty(); }
399     void write(int level, MusECore::Xml& xml) const;
400     bool read(MusECore::Xml& xml);
401 };
402 
403 
404 //-------------------------------------------------------
405 
406 
407 class MidiNamCtrl : public MidiController
408 {
409   private:
410     MidiNamValues _values;
411 
412   public:
MidiNamCtrl()413     MidiNamCtrl() : MidiController() {}
MidiNamCtrl(int number,const QString & name)414     MidiNamCtrl(int number, const QString& name) :
415                 MidiController(name, number, 0, 127, 0, -1) {}
416     bool operator<(const MidiNamCtrl& n) const { return _num < n._num; }
417     void writeMidnam(int level, MusECore::Xml& xml) const;
418     bool readMidnam(MusECore::Xml& xml);
419 };
420 
421 class MidiNamCtrls : public MidiControllerList
422 {
423   private:
424     QString _name;
425 
426     // Points to a reference.
427     MidiNamCtrls* _p_ref;
428     bool _isReference;
429 
430     bool _hasMidiNamCtrls;
431 
432   public:
MidiNamCtrls()433     MidiNamCtrls() : _p_ref(nullptr), _isReference(false), _hasMidiNamCtrls(false) { }
MidiNamCtrls(const QString & name)434     MidiNamCtrls(const QString& name) :
435       _name(name), _p_ref(nullptr), _isReference(false), _hasMidiNamCtrls(false) { }
436     MidiNamCtrls(const MidiNamCtrls& mcl);
437     // We require a destructor here because MidiControllerList
438     //  does not delete its contents.
439     ~MidiNamCtrls();
440 
hasMidiNamCtrls()441     bool hasMidiNamCtrls() const { return _hasMidiNamCtrls; }
objectOrRef()442     const MidiNamCtrls* objectOrRef() const { return (_isReference && _p_ref) ? _p_ref : this; }
objectOrRef()443     MidiNamCtrls* objectOrRef() { return (_isReference && _p_ref) ? _p_ref : this; }
setObjectOrRef(MidiNamCtrls * l)444     void setObjectOrRef(MidiNamCtrls* l) { _p_ref = l; }
resetObjectOrRef()445     void resetObjectOrRef() { _p_ref = nullptr; }
446     bool gatherReferences(MidNamReferencesList* refs) const;
name()447     const QString& name() const { return _name; }
setName(const QString & name)448     void setName(const QString& name) { _name = name; }
isReference()449     bool isReference() const { return _isReference; }
setIsReference(bool v)450     void setIsReference(bool v) { _isReference = v; }
451     void writeMidnam(int level, MusECore::Xml& xml) const;
452     void readMidnam(MusECore::Xml& xml);
453 
454     // Find the list of controllers for a channel and/or patch.
455     // If channel is -1 or patch is don't care, it looks for defaults.
456     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
457 };
458 
459 
460 //-----------------------------------------------------------------
461 
462 
463 class MidiNamPatch
464 {
465   private:
466     QString _number;
467     QString _name;
468     int _patchNumber;
469 
470     MidiNamMIDICommands _patchMIDICommands;
471 
472     MidiNamChannelNameSetAssignments _channelNameSetAssignments;
473 
474     MidNamNoteNameList _noteNameList;
475     MidiNamCtrls _controlNameList;
476 
477   public:
_patchNumber(patchNumber)478     MidiNamPatch(int patchNumber = CTRL_PROGRAM_VAL_DONT_CARE) : _patchNumber(patchNumber) {}
479     MidiNamPatch(const QString& number, const QString& name, int patchNumber = CTRL_PROGRAM_VAL_DONT_CARE) :
_number(number)480                 _number(number), _name(name), _patchNumber(patchNumber) {}
patchNumber()481     int patchNumber() const { return _patchNumber; }
patchMIDICommands()482     MidiNamMIDICommands& patchMIDICommands() { return _patchMIDICommands; }
patchMIDICommands()483     const MidiNamMIDICommands& patchMIDICommands() const { return _patchMIDICommands; }
channelNameSetAssignments()484     MidiNamChannelNameSetAssignments& channelNameSetAssignments() { return _channelNameSetAssignments; }
channelNameSetAssignments()485     const MidiNamChannelNameSetAssignments& channelNameSetAssignments() const { return _channelNameSetAssignments; }
noteNameList()486     MidNamNoteNameList& noteNameList() { return _noteNameList; }
noteNameList()487     const MidNamNoteNameList& noteNameList() const { return _noteNameList; }
controlNameList()488     MidiNamCtrls& controlNameList() { return _controlNameList; }
controlNameList()489     const MidiNamCtrls& controlNameList() const { return _controlNameList; }
490     bool gatherReferences(MidNamReferencesList* refs) const;
name()491     const QString& name() const { return _name; }
setName(const QString & name)492     void setName(const QString& name) { _name = name; }
493     bool operator<(const MidiNamPatch& n) const { return _patchNumber < n._patchNumber; }
494     void write(int level, MusECore::Xml& xml) const;
495     bool read(MusECore::Xml& xml);
496 
497     // Find the list of controllers for a channel and/or patch.
498     // If channel is -1 or patch is don't care, it looks for defaults.
499     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
500 
501     bool getNoteSampleName(
502       bool drum, int channel, int patch, int note, QString* name) const;
503 };
504 
505 class MidiNamPatchNameList : public std::map<int /* patchNumber */, MidiNamPatch*, std::less<int>>
506 {
507   private:
508     // Optional.
509     QString _name;
510 
511     // Points to a reference.
512     MidiNamPatchNameList* _p_ref;
513     bool _isReference;
514 
515   public:
MidiNamPatchNameList()516     MidiNamPatchNameList() : _p_ref(nullptr), _isReference(false) {}
MidiNamPatchNameList(const QString & name)517     MidiNamPatchNameList(const QString& name) :
518       _name(name), _p_ref(nullptr), _isReference(false) { }
519     MidiNamPatchNameList(const MidiNamPatchNameList& m);
520     ~MidiNamPatchNameList();
521     bool add(MidiNamPatch* a);
objectOrRef()522     const MidiNamPatchNameList* objectOrRef() const { return (_isReference && _p_ref) ? _p_ref : this; }
objectOrRef()523     MidiNamPatchNameList* objectOrRef() { return (_isReference && _p_ref) ? _p_ref : this; }
setObjectOrRef(MidiNamPatchNameList * l)524     void setObjectOrRef(MidiNamPatchNameList* l) { _p_ref = l; }
resetObjectOrRef()525     void resetObjectOrRef() { _p_ref = nullptr; }
526     bool gatherReferences(MidNamReferencesList* refs) const;
name()527     const QString& name() const { return _name; }
setName(const QString & name)528     void setName(const QString& name) { _name = name; }
isReference()529     bool isReference() const { return _isReference; }
setIsReference(bool v)530     void setIsReference(bool v) { _isReference = v; }
531     bool operator<(const MidiNamPatchNameList& n) const { return _name < n._name; }
532     void write(int level, MusECore::Xml& xml) const;
533     void read(MusECore::Xml& xml);
534 
535     // Like find but if bank high or low are valid,
536     //  it searches for a match using them.
537     // Whereas find searches for an exact match.
538     const MidiNamPatch* findPatch(int patch, int bankHL = 0xffff) const;
539 
540     bool getNoteSampleName(
541       bool drum, int channel, int patch, int note, QString* name, int bankHL = 0xffff) const;
542 };
543 typedef MidiNamPatchNameList::iterator iMidiNamPatchNameList;
544 typedef MidiNamPatchNameList::const_iterator ciMidiNamPatchNameList;
545 typedef std::pair<int /* patchNumber */, MidiNamPatch*> MidiNamPatchNameListPair;
546 
547 
548 //-----------------------------------------------------------------
549 
550 
551 class MidiNamPatchBank
552 {
553   private:
554     QString _name;
555     bool _ROM;
556 
557     MidiNamMIDICommands _MIDICommands;
558     // If bank high or low control commands are detected,
559     //  this value is set to them. Otherwise it is
560     //  set at 'unknown' (default) bank high and low 0xffff.
561     int _bankHL;
562 
563     MidiNamPatchNameList _patchNameList;
564 
565   public:
MidiNamPatchBank()566     MidiNamPatchBank() : _ROM(false), _bankHL(0xffff) {}
MidiNamPatchBank(const QString & name,bool ROM)567     MidiNamPatchBank(const QString& name, bool ROM) :
568                 _name(name), _ROM(ROM), _bankHL(0xffff) {}
patchNameList()569     MidiNamPatchNameList& patchNameList() { return _patchNameList; }
patchNameList()570     const MidiNamPatchNameList& patchNameList() const { return _patchNameList; }
MIDICommands()571     MidiNamMIDICommands& MIDICommands() { return _MIDICommands; }
MIDICommands()572     const MidiNamMIDICommands& MIDICommands() const { return _MIDICommands; }
bankHL()573     int bankHL() const { return _bankHL; }
574     bool gatherReferences(MidNamReferencesList* refs) const;
name()575     const QString& name() const { return _name; }
setName(const QString & name)576     void setName(const QString& name) { _name = name; }
577     bool operator<(const MidiNamPatchBank& n) const { return _bankHL < n._bankHL; }
578     void write(int level, MusECore::Xml& xml) const;
579     bool read(MusECore::Xml& xml);
580 
581     // Like find but if bank high or low are valid,
582     //  it searches for a match using them.
583     // Whereas find searches for an exact match.
584     const MidiNamPatch* findPatch(int patch) const;
585 
586     bool getNoteSampleName(
587       bool drum, int channel, int patch, int note, QString* name) const;
588 };
589 
590 class MidiNamPatchBankList : public std::map<int /* bankHL */, MidiNamPatchBank*, std::less<int>>
591 {
592   public:
MidiNamPatchBankList()593     MidiNamPatchBankList() { }
594     MidiNamPatchBankList(const MidiNamPatchBankList& m);
595     ~MidiNamPatchBankList();
596     bool add(MidiNamPatchBank* a);
597     bool gatherReferences(MidNamReferencesList* refs) const;
598     void write(int level, MusECore::Xml& xml) const;
599 
600     // Like find but if bank high or low are valid,
601     //  it searches for a match using them.
602     // Whereas find searches for an exact match.
603     const MidiNamPatch* findPatch(int patch) const;
604 
605     bool getNoteSampleName(
606       bool drum, int channel, int patch, int note, QString* name) const;
607 };
608 typedef MidiNamPatchBankList::iterator iMidiNamPatchBankList;
609 typedef MidiNamPatchBankList::const_iterator ciMidiNamPatchBankList;
610 typedef std::pair<int /* bankHL */, MidiNamPatchBank*> MidiNamPatchBankListPair;
611 
612 
613 //-----------------------------------------------------------------
614 
615 class MidNamChannelNameSet
616 {
617   private:
618     QString _name;
619 
620     MidiNamAvailableForChannels _availableForChannels;
621 
622     MidNamNoteNameList _noteNameList;
623     MidiNamCtrls _controlNameList;
624     MidiNamPatchBankList _patchBankList;
625 
626   public:
MidNamChannelNameSet()627     MidNamChannelNameSet() {}
MidNamChannelNameSet(const QString & name)628     MidNamChannelNameSet(
629       const QString& name) :
630       _name(name) {}
name()631     const QString& name() const { return _name; }
setName(const QString & nameSet)632     void setName(const QString& nameSet) {
633         _name = nameSet; }
634     bool gatherReferences(MidNamReferencesList* refs) const;
635     bool operator<(const MidNamChannelNameSet& n) const { return _name < n._name; }
636     void write(int level, MusECore::Xml& xml) const;
637     bool read(MusECore::Xml& xml);
638 
639     // Like find but if bank high or low are valid,
640     //  it searches for a match using them.
641     // Whereas find searches for an exact match.
642     const MidiNamPatch* findPatch(int channel, int patch) const;
643 
644     const MidiNamPatchBankList* getPatchBanks(int channel) const;
645 
646     // Find the list of controllers for a channel and/or patch.
647     // If channel is -1 or patch is don't care, it looks for defaults.
648     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
649 
650     bool getNoteSampleName(
651       bool drum, int channel, int patch, int note, QString* name) const;
652 };
653 
654 class MidiNamChannelNameSetList : public std::map<QString /* name */, MidNamChannelNameSet*, std::less<QString>>
655 {
656   public:
MidiNamChannelNameSetList()657     MidiNamChannelNameSetList() { }
658     MidiNamChannelNameSetList(const MidiNamChannelNameSetList& m);
659     ~MidiNamChannelNameSetList();
660     bool add(MidNamChannelNameSet* a);
661     bool gatherReferences(MidNamReferencesList* refs) const;
662     void write(int level, MusECore::Xml& xml) const;
663 
664     // Like find but if bank high or low are valid,
665     //  it searches for a match using them.
666     // Whereas find searches for an exact match.
667     const MidiNamPatch* findPatch(int channel, int patch) const;
668 
669     const MidiNamPatchBankList* getPatchBanks(int channel) const;
670 
671     // Find the list of controllers for a channel and/or patch.
672     // If channel is -1 or patch is don't care, it looks for defaults.
673     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
674 
675     bool getNoteSampleName(
676       bool drum, int channel, int patch, int note, QString* name) const;
677 };
678 typedef MidiNamChannelNameSetList::iterator iMidiNamChannelNameSetList;
679 typedef MidiNamChannelNameSetList::const_iterator ciMidiNamChannelNameSetList;
680 typedef std::pair<QString /* name */, MidNamChannelNameSet*> MidiNamChannelNameSetListPair;
681 
682 
683 //-----------------------------------------------------------------
684 
685 
686 class MidNamDeviceModeEnable
687 {
688   private:
689     MidiNamMIDICommands _MIDICommands;
690 
691   public:
MidNamDeviceModeEnable()692     MidNamDeviceModeEnable() {}
MIDICommands()693     const MidiNamMIDICommands& MIDICommands() const { return _MIDICommands; }
MIDICommands()694     MidiNamMIDICommands& MIDICommands() { return _MIDICommands; }
695     void write(int level, MusECore::Xml& xml) const;
696     bool read(MusECore::Xml& xml);
697 };
698 
699 class MidNamDeviceModeDisable
700 {
701   private:
702     MidiNamMIDICommands _MIDICommands;
703 
704   public:
MidNamDeviceModeDisable()705     MidNamDeviceModeDisable() {}
MIDICommands()706     const MidiNamMIDICommands& MIDICommands() const { return _MIDICommands; }
MIDICommands()707     MidiNamMIDICommands& MIDICommands() { return _MIDICommands; }
708     void write(int level, MusECore::Xml& xml) const;
709     bool read(MusECore::Xml& xml);
710 };
711 
712 
713 //-----------------------------------------------------------------
714 
715 
716 class MidNamNameList
717 {
718   private:
719     MidiNamPatchNameList _patchNameList;
720     MidNamNoteNameList _noteNameList;
721     MidiNamCtrls _controlNameList;
722     MidiNamValNames _valueNameList;
723 
724   public:
MidNamNameList()725     MidNamNameList() {}
726     bool gatherReferences(MidNamReferencesList* refs) const;
empty()727     bool empty() const {
728       return _patchNameList.empty() &&
729       _noteNameList.empty() &&
730       _controlNameList.empty() &&
731       _valueNameList.empty();
732     }
733     void write(int level, MusECore::Xml& xml) const;
734     bool read(MusECore::Xml& xml);
735 };
736 
737 
738 //-----------------------------------------------------------------
739 
740 
741 class MidNamDeviceMode
742 {
743   private:
744     QString _name;
745     // Whether this is a StandardDeviceMode or CustomDeviceMode.
746     bool _isCustomDeviceMode;
747 
748     MidNamDeviceModeEnable _deviceModeEnable;
749     MidNamDeviceModeDisable _deviceModeDisable;
750 
751     MidiNamChannelNameSetAssignments _channelNameSetAssignments;
752     MidNamNameList _nameList;
753     // Used only with StandardDeviceMode.
754     MidiNamChannelNameSetList _channelNameSetList;
755 
756     // Points to a reference (a SupportsStandardDeviceMode reference to a StandardDeviceMode).
757     MidNamDeviceMode* _p_ref;
758     bool _isReference;
759 
760   public:
MidNamDeviceMode()761     MidNamDeviceMode() : _isCustomDeviceMode(false), _p_ref(nullptr), _isReference(false) {}
MidNamDeviceMode(const QString & name)762     MidNamDeviceMode(
763       const QString& name) :
764       _name(name), _isCustomDeviceMode(false), _p_ref(nullptr), _isReference(false) {}
objectOrRef()765     const MidNamDeviceMode* objectOrRef() const { return (_isReference && _p_ref) ? _p_ref : this; }
objectOrRef()766     MidNamDeviceMode* objectOrRef() { return (_isReference && _p_ref) ? _p_ref : this; }
setObjectOrRef(MidNamDeviceMode * l)767     void setObjectOrRef(MidNamDeviceMode* l) { _p_ref = l; }
resetObjectOrRef()768     void resetObjectOrRef() { _p_ref = nullptr; }
769     bool gatherReferences(MidNamReferencesList* refs) const;
isCustomDeviceMode()770     bool isCustomDeviceMode() const { return _isCustomDeviceMode; }
setCustomDeviceMode(bool v)771     void setCustomDeviceMode(bool v) { _isCustomDeviceMode = v; }
deviceModeEnable()772     const MidNamDeviceModeEnable& deviceModeEnable() const { return _deviceModeEnable; }
deviceModeEnable()773     MidNamDeviceModeEnable& deviceModeEnable() { return _deviceModeEnable; }
deviceModeDisable()774     const MidNamDeviceModeDisable& deviceModeDisable() const { return _deviceModeDisable; }
deviceModeDisable()775     MidNamDeviceModeDisable& deviceModeDisable() { return _deviceModeDisable; }
channelNameSetAssignments()776     const MidiNamChannelNameSetAssignments& channelNameSetAssignments() const { return _channelNameSetAssignments; }
channelNameSetAssignments()777     MidiNamChannelNameSetAssignments& channelNameSetAssignments() { return _channelNameSetAssignments; }
nameList()778     const MidNamNameList& nameList() const { return _nameList; }
nameList()779     MidNamNameList& nameList() { return _nameList; }
channelNameSetList()780     const MidiNamChannelNameSetList& channelNameSetList() const { return _channelNameSetList; }
channelNameSetList()781     MidiNamChannelNameSetList& channelNameSetList() { return _channelNameSetList; }
name()782     const QString& name() const { return _name; }
isReference()783     bool isReference() const { return _isReference; }
setIsReference(bool v)784     void setIsReference(bool v) { _isReference = v; }
785     bool operator<(const MidNamDeviceMode& n) const { return _name < n._name; }
786     void write(int level, MusECore::Xml& xml) const;
787     bool read(MusECore::Xml& xml);
788 
789     // Like find but if bank high or low are valid,
790     //  it searches for a match using them.
791     // Whereas find searches for an exact match.
792     const MidiNamPatch* findPatch(int channel, int patch) const;
793 
794     const MidiNamPatchBankList* getPatchBanks(int channel) const;
795 
796     // Find the list of controllers for a channel and/or patch.
797     // If channel is -1 or patch is don't care, it looks for defaults.
798     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
799 
800     bool getNoteSampleName(
801       bool drum, int channel, int patch, int note, QString* name) const;
802 };
803 
804 class MidNamDeviceModeList : public std::map<QString /* name */, MidNamDeviceMode*, std::less<QString>>
805 {
806   public:
MidNamDeviceModeList()807     MidNamDeviceModeList() { }
808     MidNamDeviceModeList(const MidNamDeviceModeList& m);
809     ~MidNamDeviceModeList();
810     bool add(MidNamDeviceMode* a);
811     bool gatherReferences(MidNamReferencesList* refs) const;
812     void write(int level, MusECore::Xml& xml) const;
813 };
814 typedef MidNamDeviceModeList::iterator iMidNamDeviceModeList;
815 typedef MidNamDeviceModeList::const_iterator ciMidNamDeviceModeList;
816 typedef std::pair<QString /* name */, MidNamDeviceMode*> MidNamDeviceModeListPair;
817 
818 
819 //-----------------------------------------------------------------
820 
821 
822 class MidNamDevice
823 {
824   private:
825     QString _name;
826     int _uniqueID;
827 
828   public:
MidNamDevice()829     MidNamDevice() : _uniqueID(0) {}
MidNamDevice(const QString & name,int uniqueID)830     MidNamDevice(const QString& name, int uniqueID) :
831                 _name(name), _uniqueID(uniqueID) {}
name()832     const QString& name() const { return _name; }
uniqueID()833     int uniqueID() const { return _uniqueID; }
834     bool operator<(const MidNamDevice& n) const { return _uniqueID < n._uniqueID; }
835     void write(int level, MusECore::Xml& xml) const;
836     bool read(MusECore::Xml& xml);
837 };
838 
839 
840 //-----------------------------------------------------------------
841 
842 
843 class MidNamModel
844 {
845   private:
846     QString _model;
847 
848   public:
MidNamModel()849     MidNamModel() {}
MidNamModel(const QString & model)850     MidNamModel(const QString& model) :
851                 _model(model) {}
model()852     const QString& model() const { return _model; }
853     bool operator<(const MidNamModel& n) const { return _model < n._model; }
854     void write(int level, MusECore::Xml& xml) const;
855     bool read(MusECore::Xml& xml);
856 };
857 
858 class MidiNamModelList : public std::map<QString /* model */, MidNamModel*, std::less<QString>>
859 {
860   public:
MidiNamModelList()861     MidiNamModelList() { }
862     MidiNamModelList(const MidiNamModelList& m);
863     ~MidiNamModelList();
864     bool add(MidNamModel* a);
865     void write(int level, MusECore::Xml& xml) const;
866 };
867 typedef MidiNamModelList::iterator iMidiNamModelList;
868 typedef MidiNamModelList::const_iterator ciMidiNamModelList;
869 typedef std::pair<QString /* model */, MidNamModel*> MidiNamModelListPair;
870 
871 
872 //-----------------------------------------------------------------
873 
874 
875 class MidNamManufacturer
876 {
877   private:
878     QString _manufacturer;
879 
880   public:
MidNamManufacturer()881     MidNamManufacturer() {}
MidNamManufacturer(const QString & manufacturer)882     MidNamManufacturer(const QString& manufacturer) :
883                 _manufacturer(manufacturer) {}
manufacturer()884     const QString& manufacturer() const { return _manufacturer; }
885     bool operator<(const MidNamManufacturer& n) const { return _manufacturer < n._manufacturer; }
886     void write(int level, MusECore::Xml& xml) const;
887     bool read(MusECore::Xml& xml);
888 };
889 
890 
891 //-----------------------------------------------------------------
892 
893 
894 class MidNamAuthor
895 {
896   private:
897     QString _author;
898 
899   public:
MidNamAuthor()900     MidNamAuthor() {}
MidNamAuthor(const QString & author)901     MidNamAuthor(const QString& author) :
902                 _author(author) {}
author()903     const QString& author() const { return _author; }
clear()904     void clear() { _author.clear(); }
905     bool operator<(const MidNamAuthor& n) const { return _author < n._author; }
906     void write(int level, MusECore::Xml& xml) const;
907     bool read(MusECore::Xml& xml);
908 };
909 
910 
911 //-----------------------------------------------------------------
912 
913 
914 class MidNamExtendingDeviceNames
915 {
916   private:
917     MidNamManufacturer _manufacturer;
918     MidiNamModelList _modelList;
919     MidNamDevice _device;
920     MidNamNameList _nameList;
921 
922   public:
MidNamExtendingDeviceNames()923     MidNamExtendingDeviceNames() {}
924     bool gatherReferences(MidNamReferencesList* refs) const;
manufacturer()925     MidNamManufacturer& manufacturer() { return _manufacturer; }
modelList()926     MidiNamModelList& modelList() { return _modelList; }
device()927     MidNamDevice& device() { return _device; }
nameList()928     MidNamNameList& nameList() { return _nameList; }
929     void write(int level, MusECore::Xml& xml) const;
930     bool read(MusECore::Xml& xml);
931 };
932 
933 class MidNamExtendingDeviceNamesList : public std::list<MidNamExtendingDeviceNames*>
934 {
935   public:
MidNamExtendingDeviceNamesList()936     MidNamExtendingDeviceNamesList() { }
937     MidNamExtendingDeviceNamesList(const MidNamExtendingDeviceNamesList& m);
938     ~MidNamExtendingDeviceNamesList();
939     bool gatherReferences(MidNamReferencesList* refs) const;
940     void write(int level, MusECore::Xml& xml) const;
941 };
942 typedef MidNamExtendingDeviceNamesList::iterator iMidNamExtendingDeviceNamesList;
943 typedef MidNamExtendingDeviceNamesList::const_iterator ciMidNamExtendingDeviceNamesList;
944 
945 
946 //-----------------------------------------------------------------
947 
948 
949 class MidNamMasterDeviceNames
950 {
951   private:
952     MidNamManufacturer _manufacturer;
953     MidiNamModelList _modelList;
954     MidNamDevice _device;
955     MidNamDeviceModeList _deviceModeList;
956     MidiNamChannelNameSetList _channelNameSetList;
957     MidNamNameList _nameList;
958 
959   public:
MidNamMasterDeviceNames()960     MidNamMasterDeviceNames() {}
961     bool gatherReferences(MidNamReferencesList* refs) const;
manufacturer()962     MidNamManufacturer& manufacturer() { return _manufacturer; }
modelList()963     MidiNamModelList& modelList() { return _modelList; }
device()964     MidNamDevice& device() { return _device; }
deviceModeList()965     const MidNamDeviceModeList* deviceModeList() const { return &_deviceModeList; }
channelNameSetList()966     MidiNamChannelNameSetList& channelNameSetList() { return _channelNameSetList; }
nameList()967     MidNamNameList& nameList() { return _nameList; }
968     void write(int level, MusECore::Xml& xml) const;
969     bool read(MusECore::Xml& xml);
970 
971     // Like find but if bank high or low are valid,
972     //  it searches for a match using them.
973     // Whereas find searches for an exact match.
974     const MidiNamPatch* findPatch(int channel, int patch) const;
975 
976     const MidiNamPatchBankList* getPatchBanks(int channel) const;
977 
978     bool getNoteSampleName(
979       bool drum, int channel, int patch, int note, QString* name) const;
980 };
981 
982 class MidNamMasterDeviceNamesList : public std::list<MidNamMasterDeviceNames*>
983 {
984   public:
MidNamMasterDeviceNamesList()985     MidNamMasterDeviceNamesList() { }
986     MidNamMasterDeviceNamesList(const MidNamMasterDeviceNamesList& m);
987     ~MidNamMasterDeviceNamesList();
988     bool gatherReferences(MidNamReferencesList* refs) const;
989     void write(int level, MusECore::Xml& xml) const;
990 };
991 typedef MidNamMasterDeviceNamesList::iterator iMidNamMasterDeviceNamesList;
992 typedef MidNamMasterDeviceNamesList::const_iterator ciMidNamMasterDeviceNamesList;
993 
994 
995 //-----------------------------------------------------------------
996 
997 
998 // T is a pointer to one of the reference lists, such as MidNamNoteNameList.
999 template<class T, class Compare = std::less<T>, class Alloc = std::allocator<T> >
1000   class MidNamReferenceList_t : public std::set<T, Compare, Alloc >
1001 {
1002   private:
1003     typedef std::set<T, Compare, Alloc> vlist;
1004 
1005   public:
1006     typedef typename vlist::iterator iMidNamReferenceList_t;
1007     typedef typename vlist::const_iterator ciMidNamReferenceList_t;
1008     typedef std::pair <iMidNamReferenceList_t, bool> MidNamReferenceListPair_t;
1009 
add(const T t)1010     bool add(const T t)
1011     {
1012       // Make sure it has a name!
1013       if(t->name().isEmpty())
1014         return false;
1015       MidNamReferenceListPair_t pr = vlist::insert(t);
1016       return pr.second;
1017     }
1018 };
1019 
1020 typedef MidNamReferenceList_t<MidNamNoteNameList*>   MidNamNoteNameListRefs_t;
1021 typedef MidNamReferenceList_t<MidiNamValNames*>      MidiNamValNamesRefs_t;
1022 typedef MidNamReferenceList_t<MidiNamCtrls*>         MidiNamCtrlsRefs_t;
1023 typedef MidNamReferenceList_t<MidiNamPatchNameList*> MidiNamPatchNameListRefs_t;
1024 typedef MidNamReferenceList_t<MidNamDeviceMode*>     MidNamDeviceModeRefs_t;
1025 typedef MidNamReferenceList_t<MidiNamChannelNameSetAssign*> MidiNamChannelNameSetAssignRefs_t;
1026 typedef MidNamReferenceList_t<MidNamChannelNameSet*> MidNamChannelNameSetRefs_t;
1027 
1028 struct MidNamReferencesList
1029 {
1030   MidNamNoteNameListRefs_t   noteNameListObjs;
1031   MidiNamValNamesRefs_t      valNamesObjs;
1032   MidiNamCtrlsRefs_t         ctrlsObjs;
1033   MidiNamPatchNameListRefs_t patchNameListObjs;
1034   MidNamDeviceModeRefs_t     deviceModeObjs;
1035   MidiNamChannelNameSetAssignRefs_t channelNameSetAssignObjs;
1036   MidNamChannelNameSetRefs_t channelNameSetObjs;
1037 
1038   bool resolveReferences() const;
1039 };
1040 
1041 //-----------------------------------------------------------------
1042 
1043 
1044 class MidNamMIDINameDocument
1045 {
1046   private:
1047     MidNamAuthor _author;
1048     MidNamMasterDeviceNamesList _masterDeviceNamesList;
1049     MidNamExtendingDeviceNamesList _extendingDeviceNamesList;
1050     MidNamDeviceModeList _standardDeviceModeList;
1051 
1052   public:
MidNamMIDINameDocument()1053     MidNamMIDINameDocument() {}
clear()1054     void clear() {
1055       _author.clear();
1056       _masterDeviceNamesList.clear();
1057       _extendingDeviceNamesList.clear();
1058       _standardDeviceModeList.clear();
1059     }
1060     bool gatherReferences(MidNamReferencesList* refs) const;
1061     // This gathers all references and objects and resolves the references.
1062     // Run this AFTER the document has been fully read.
1063     bool resolveReferences();
author()1064     MidNamAuthor& author() { return _author; }
masterDeviceNamesList()1065     MidNamMasterDeviceNamesList& masterDeviceNamesList() { return _masterDeviceNamesList; }
extendingDeviceNamesList()1066     MidNamExtendingDeviceNamesList& extendingDeviceNamesList() { return _extendingDeviceNamesList; }
standardDeviceModeList()1067     MidNamDeviceModeList& standardDeviceModeList() { return _standardDeviceModeList; }
1068     void write(int level, MusECore::Xml& xml) const;
1069     bool read(MusECore::Xml& xml);
1070 
1071     // Like find but if bank high or low are valid,
1072     //  it searches for a match using them.
1073     // Whereas find searches for an exact match.
1074     const MidiNamPatch* findPatch(int channel, int patch) const;
1075 
1076     const MidiNamPatchBankList* getPatchBanks(int channel) const;
1077 
1078     // Find the list of controllers for a channel and/or patch.
1079     // If channel is -1 or patch is don't care, it looks for defaults.
1080     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
1081 
1082     bool getNoteSampleName(
1083       bool drum, int channel, int patch, int note, QString* name) const;
1084 };
1085 
1086 class MidNamMIDIName
1087 {
1088   private:
1089     MidNamMIDINameDocument _MIDINameDocument;
1090     // Whether the document contains anything
1091     //  ie MIDINameDocument tag was found and loaded OK.
1092     bool _isEmpty;
1093 
1094   public:
MidNamMIDIName()1095     MidNamMIDIName() : _isEmpty(true) {}
isEmpty()1096     bool isEmpty () const { return _isEmpty; }
clear()1097     void clear() { _MIDINameDocument.clear(); _isEmpty = true; }
1098     // This gathers all references and objects and resolves the references.
1099     // Run this AFTER the document has been fully read.
resolveReferences()1100     bool resolveReferences() { return _MIDINameDocument.resolveReferences(); }
1101     void write(int level, MusECore::Xml& xml) const;
1102     bool read(MusECore::Xml& xml);
1103 
1104     // Like find but if bank high or low are valid,
1105     //  it searches for a match using them.
1106     // Whereas find searches for an exact match.
1107     const MidiNamPatch* findPatch(int channel, int patch) const;
1108 
1109     const MidiNamPatchBankList* getPatchBanks(int channel) const;
1110 
1111     // Find the list of controllers for a channel and/or patch.
1112     // If channel is -1 or patch is don't care, it looks for defaults.
1113     const MidiControllerList* getControllers(int channel = -1, int patch = CTRL_PROGRAM_VAL_DONT_CARE) const;
1114 
1115     bool getNoteSampleName(
1116       bool drum, int channel, int patch, int note, QString* name) const;
1117 };
1118 
1119 class MidNamMIDINameDocumentList : public std::list<MidNamMIDINameDocument>
1120 {
1121   public:
1122     void write(int level, MusECore::Xml& xml) const;
1123     bool read(MusECore::Xml& xml);
1124 };
1125 typedef MidNamMIDINameDocumentList::iterator iMidNamMIDINameDocumentList;
1126 typedef MidNamMIDINameDocumentList::const_iterator ciMidNamMIDINameDocumentList;
1127 
1128 
1129 //-----------------------------------------------------------------
1130 
1131 
1132 } // namespace MusECore
1133 
1134 #endif
1135