2 Copyright (C) 2012 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef MIDNAM_PATCH_H_
21 #define MIDNAM_PATCH_H_
33 #include "midi++/libmidi_visibility.h"
34 #include "midi++/event.h"
35 #include "pbd/xml++.h"
43 struct LIBMIDIPP_API PatchPrimaryKey
49 PatchPrimaryKey (uint8_t a_program_number = 0, uint16_t a_bank_number = 0) {
50 bank_number = std::min (a_bank_number, (uint16_t) 16384);
51 program_number = std::min (a_program_number, (uint8_t) 127);
54 bool is_sane() const {
55 return ((bank_number >= 0) && (bank_number <= 16384) &&
56 (program_number >=0 ) && (program_number <= 127));
59 inline PatchPrimaryKey& operator=(const PatchPrimaryKey& id) {
60 bank_number = id.bank_number;
61 program_number = id.program_number;
65 inline bool operator==(const PatchPrimaryKey& id) const {
66 return (bank_number == id.bank_number && program_number == id.program_number);
70 * obey strict weak ordering or crash in STL containers
72 inline bool operator<(const PatchPrimaryKey& id) const {
73 if (bank_number < id.bank_number) {
75 } else if (bank_number == id.bank_number && program_number < id.program_number) {
85 class LIBMIDIPP_API Patch
89 Patch (std::string a_name = std::string(), uint8_t a_number = 0, uint16_t bank_number = 0);
92 const std::string& name() const { return _name; }
93 void set_name(const std::string& name) { _name = name; }
95 const std::string& note_list_name() const { return _note_list_name; }
97 uint8_t program_number() const { return _id.program_number; }
98 void set_program_number(uint8_t n) { _id.program_number = n; }
100 uint16_t bank_number() const { return _id.bank_number; }
101 void set_bank_number (uint16_t n) { _id.bank_number = n; }
103 const PatchPrimaryKey& patch_primary_key() const { return _id; }
105 XMLNode& get_state (void);
106 int set_state (const XMLTree&, const XMLNode&);
111 std::string _note_list_name;
114 typedef std::list<boost::shared_ptr<Patch> > PatchNameList;
116 class LIBMIDIPP_API PatchBank
119 PatchBank (uint16_t n = 0, std::string a_name = std::string()) : _name(a_name), _number (n) {};
120 virtual ~PatchBank() { }
122 const std::string& name() const { return _name; }
123 void set_name(const std::string& a_name) { _name = a_name; }
125 int number() const { return _number; }
127 const PatchNameList& patch_name_list() const { return _patch_name_list; }
128 const std::string& patch_list_name() const { return _patch_list_name; }
130 int set_patch_name_list (const PatchNameList&);
132 XMLNode& get_state (void);
133 int set_state (const XMLTree&, const XMLNode&);
138 PatchNameList _patch_name_list;
139 std::string _patch_list_name;
142 class LIBMIDIPP_API ChannelNameSet
145 typedef std::set<uint8_t> AvailableForChannels;
146 typedef std::list<boost::shared_ptr<PatchBank> > PatchBanks;
147 typedef std::map<PatchPrimaryKey, boost::shared_ptr<Patch> > PatchMap;
148 typedef std::list<PatchPrimaryKey> PatchList;
151 virtual ~ChannelNameSet() {};
152 ChannelNameSet(std::string& name) : _name(name) {};
154 const std::string& name() const { return _name; }
155 void set_name(const std::string& name) { _name = name; }
157 const PatchBanks& patch_banks() const { return _patch_banks; }
159 bool available_for_channel(uint8_t channel) const {
160 return _available_for_channels.find(channel) != _available_for_channels.end();
163 boost::shared_ptr<Patch> find_patch(const PatchPrimaryKey& key) {
164 assert(key.is_sane());
165 return _patch_map[key];
168 boost::shared_ptr<Patch> previous_patch(const PatchPrimaryKey& key) {
169 assert(key.is_sane());
170 for (PatchList::const_iterator i = _patch_list.begin();
171 i != _patch_list.end();
174 if (i != _patch_list.begin()) {
176 return _patch_map[*i];
181 return boost::shared_ptr<Patch>();
184 boost::shared_ptr<Patch> next_patch(const PatchPrimaryKey& key) {
185 assert(key.is_sane());
186 for (PatchList::const_iterator i = _patch_list.begin();
187 i != _patch_list.end();
190 if (++i != _patch_list.end()) {
191 return _patch_map[*i];
198 return boost::shared_ptr<Patch>();
201 const std::string& note_list_name() const { return _note_list_name; }
202 const std::string& control_list_name() const { return _control_list_name; }
204 XMLNode& get_state (void);
205 int set_state (const XMLTree&, const XMLNode&);
207 void set_patch_banks (const PatchBanks&);
208 void use_patch_name_list (const PatchNameList&);
211 friend std::ostream& operator<< (std::ostream&, const ChannelNameSet&);
214 AvailableForChannels _available_for_channels;
215 PatchBanks _patch_banks;
217 PatchList _patch_list;
218 std::string _patch_list_name;
219 std::string _note_list_name;
220 std::string _control_list_name;
223 std::ostream& operator<< (std::ostream&, const ChannelNameSet&);
225 class LIBMIDIPP_API Note
229 Note(uint8_t number, const std::string& name) : _number(number), _name(name) {}
231 const std::string& name() const { return _name; }
232 void set_name(const std::string& name) { _name = name; }
234 uint8_t number() const { return _number; }
235 void set_number(uint8_t number) { _number = number; }
237 XMLNode& get_state (void);
238 int set_state (const XMLTree&, const XMLNode&);
245 class LIBMIDIPP_API NoteNameList
248 typedef std::vector< boost::shared_ptr<Note> > Notes;
250 NoteNameList() { _notes.resize(128); }
251 NoteNameList (const std::string& name) : _name(name) { _notes.resize(128); }
253 const std::string& name() const { return _name; }
254 const Notes& notes() const { return _notes; }
256 void set_name(const std::string& name) { _name = name; }
258 XMLNode& get_state (void);
259 int set_state (const XMLTree&, const XMLNode&);
266 class LIBMIDIPP_API Value
270 Value(const uint16_t number,
271 const std::string& name)
276 uint16_t number() const { return _number; }
277 const std::string& name() const { return _name; }
279 void set_number(uint16_t number) { _number = number; }
280 void set_name(const std::string& name) { _name = name; }
282 XMLNode& get_state(void);
283 int set_state(const XMLTree&, const XMLNode&);
290 class LIBMIDIPP_API ValueNameList
293 typedef std::map<uint16_t, boost::shared_ptr<Value> > Values;
296 ValueNameList(const std::string& name) : _name(name) {}
298 const std::string& name() const { return _name; }
300 void set_name(const std::string& name) { _name = name; }
302 boost::shared_ptr<const Value> value(uint16_t num) const;
303 boost::shared_ptr<const Value> max_value_below(uint16_t num) const;
305 const Values& values() const { return _values; }
307 XMLNode& get_state(void);
308 int set_state(const XMLTree&, const XMLNode&);
315 class LIBMIDIPP_API Control
319 Control(const std::string& type,
320 const uint16_t number,
321 const std::string& name)
327 const std::string& type() const { return _type; }
328 uint16_t number() const { return _number; }
329 const std::string& name() const { return _name; }
331 const std::string& value_name_list_name() const { return _value_name_list_name; }
332 boost::shared_ptr<const ValueNameList> value_name_list() const { return _value_name_list; }
334 void set_type(const std::string& type) { _type = type; }
335 void set_number(uint16_t number) { _number = number; }
336 void set_name(const std::string& name) { _name = name; }
338 XMLNode& get_state(void);
339 int set_state(const XMLTree&, const XMLNode&);
346 std::string _value_name_list_name; ///< Global, UsesValueNameList
347 boost::shared_ptr<ValueNameList> _value_name_list; ///< Local, ValueNameList
350 class LIBMIDIPP_API ControlNameList
353 typedef std::map<uint16_t, boost::shared_ptr<Control> > Controls;
356 ControlNameList(const std::string& name) : _name(name) {}
358 const std::string& name() const { return _name; }
360 void set_name(const std::string& name) { _name = name; }
362 boost::shared_ptr<const Control> control(uint16_t num) const;
364 const Controls& controls() const { return _controls; }
366 XMLNode& get_state(void);
367 int set_state(const XMLTree&, const XMLNode&);
374 class LIBMIDIPP_API CustomDeviceMode
377 CustomDeviceMode() {};
378 virtual ~CustomDeviceMode() {};
380 const std::string& name() const { return _name; }
381 void set_name(const std::string& name) { _name = name; }
384 XMLNode& get_state (void);
385 int set_state (const XMLTree&, const XMLNode&);
387 /// Note: channel here is 0-based while in the MIDNAM-file it's 1-based
388 const std::string& channel_name_set_name_by_channel(uint8_t channel) {
389 assert(channel <= 15);
390 return _channel_name_set_assignments[channel];
394 /// array index = channel number
395 /// string contents = name of channel name set
397 std::string _channel_name_set_assignments[16];
400 class LIBMIDIPP_API MasterDeviceNames
403 typedef std::set<std::string> Models;
404 /// maps name to CustomDeviceMode
405 typedef std::map<std::string, boost::shared_ptr<CustomDeviceMode> > CustomDeviceModes;
406 typedef std::list<std::string> CustomDeviceModeNames;
407 /// maps name to ChannelNameSet
408 typedef std::map<std::string, boost::shared_ptr<ChannelNameSet> > ChannelNameSets;
409 typedef std::map<std::string, boost::shared_ptr<NoteNameList> > NoteNameLists;
410 typedef std::map<std::string, boost::shared_ptr<ControlNameList> > ControlNameLists;
411 typedef std::map<std::string, boost::shared_ptr<ValueNameList> > ValueNameLists;
412 typedef std::map<std::string, PatchNameList> PatchNameLists;
414 MasterDeviceNames() {};
415 virtual ~MasterDeviceNames() {};
417 const std::string& manufacturer() const { return _manufacturer; }
418 void set_manufacturer(const std::string& manufacturer) { _manufacturer = manufacturer; }
420 const Models& models() const { return _models; }
421 void set_models(const Models some_models) { _models = some_models; }
423 const ControlNameLists& controls() const { return _control_name_lists; }
424 const ValueNameLists& values() const { return _value_name_lists; }
426 boost::shared_ptr<const ValueNameList> value_name_list_by_control(
427 const std::string& mode,
431 const CustomDeviceModeNames& custom_device_mode_names() const { return _custom_device_mode_names; }
433 boost::shared_ptr<CustomDeviceMode> custom_device_mode_by_name(const std::string& mode_name);
434 boost::shared_ptr<ChannelNameSet> channel_name_set_by_channel(const std::string& mode, uint8_t channel);
435 boost::shared_ptr<Patch> find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key);
437 boost::shared_ptr<ControlNameList> control_name_list(const std::string& name);
438 boost::shared_ptr<ValueNameList> value_name_list(const std::string& name);
439 boost::shared_ptr<NoteNameList> note_name_list(const std::string& name);
440 boost::shared_ptr<ChannelNameSet> channel_name_set(const std::string& name);
442 std::string note_name(const std::string& mode_name,
448 XMLNode& get_state (void);
449 int set_state (const XMLTree&, const XMLNode&);
452 std::string _manufacturer;
454 CustomDeviceModes _custom_device_modes;
455 CustomDeviceModeNames _custom_device_mode_names;
456 ChannelNameSets _channel_name_sets;
457 NoteNameLists _note_name_lists;
458 PatchNameLists _patch_name_lists;
459 ControlNameLists _control_name_lists;
460 ValueNameLists _value_name_lists;
463 class LIBMIDIPP_API MIDINameDocument
466 // Maps Model names to MasterDeviceNames
467 typedef std::map<std::string, boost::shared_ptr<MasterDeviceNames> > MasterDeviceNamesList;
469 MIDINameDocument() {}
470 MIDINameDocument(const std::string& filename);
471 virtual ~MIDINameDocument() {};
473 const std::string& author() const { return _author; }
474 void set_author(const std::string& author) { _author = author; }
476 boost::shared_ptr<MasterDeviceNames> master_device_names(const std::string& model);
478 const MasterDeviceNamesList& master_device_names_by_model() const { return _master_device_names_list; }
480 const MasterDeviceNames::Models& all_models() const { return _all_models; }
482 XMLNode& get_state (void);
483 int set_state (const XMLTree&, const XMLNode&);
487 MasterDeviceNamesList _master_device_names_list;
488 MasterDeviceNames::Models _all_models;
491 LIBMIDIPP_API extern const char* general_midi_program_names[128]; /* 0 .. 127 */
496 #endif /*MIDNAM_PATCH_H_*/