2 Copyright (C) 2008 Hans Baier
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #ifndef MIDNAM_PATCH_H_
22 #define MIDNAM_PATCH_H_
29 #include "pbd/stateful.h"
30 #include "midi++/event.h"
31 #include "pbd/xml++.h"
39 struct PatchPrimaryKey
46 PatchPrimaryKey(int a_msb = -1, int a_lsb = -1, int a_program_number = -1) {
49 program_number = a_program_number;
53 return ((msb >= 0) && (msb <= 127) &&
54 (lsb >= 0) && (lsb <= 127) &&
55 (program_number >=0 ) && (program_number <= 127));
58 inline PatchPrimaryKey& operator=(const PatchPrimaryKey& id) {
61 program_number = id.program_number;
65 inline bool operator==(const PatchPrimaryKey& id) const {
66 return (msb == id.msb && lsb == id.lsb && program_number == id.program_number);
70 * obey strict weak ordering or crash in STL containers
72 inline bool operator<(const PatchPrimaryKey& id) const {
75 } else if (msb == id.msb && lsb < id.lsb) {
77 } else if (lsb == id.lsb && program_number < id.program_number) {
85 class Patch : public PBD::Stateful
88 typedef std::list<boost::shared_ptr<Evoral::MIDIEvent> > PatchMidiCommands;
91 Patch(string a_number, string a_name) : _number(a_number), _name(a_name) {};
94 const string& name() const { return _name; }
95 void set_name(const string a_name) { _name = a_name; }
97 const string& number() const { return _number; }
98 void set_number(const string a_number) { _number = a_number; }
100 const PatchMidiCommands& patch_midi_commands() const { return _patch_midi_commands; }
102 const PatchPrimaryKey& patch_primary_key() const { return _id; }
104 XMLNode& get_state (void);
105 int set_state (const XMLNode& a_node);
111 PatchMidiCommands _patch_midi_commands;
114 class PatchBank : public PBD::Stateful
117 typedef std::list<boost::shared_ptr<Patch> > PatchNameList;
120 virtual ~PatchBank() {};
121 PatchBank(string a_name) : _name(a_name) {};
123 const string& name() const { return _name; }
124 void set_name(const string a_name) { _name = a_name; }
126 const PatchNameList& patch_name_list() const { return _patch_name_list; }
128 XMLNode& get_state (void);
129 int set_state (const XMLNode& a_node);
133 PatchNameList _patch_name_list;
136 class ChannelNameSet : public PBD::Stateful
139 typedef std::set<uint8_t> AvailableForChannels;
140 typedef std::list<boost::shared_ptr<PatchBank> > PatchBanks;
141 typedef std::map<PatchPrimaryKey, boost::shared_ptr<Patch> > PatchMap;
144 virtual ~ChannelNameSet() {};
145 ChannelNameSet(string a_name) : _name(a_name) {};
147 const string& name() const { return _name; }
148 void set_name(const string a_name) { _name = a_name; }
150 bool available_for_channel(uint8_t channel) const {
151 return _available_for_channels.find(channel) != _available_for_channels.end();
154 boost::shared_ptr<Patch> find_patch(PatchPrimaryKey& key) {
155 assert(key.is_sane());
156 return _patch_map[key];
159 boost::shared_ptr<Patch> previous_patch(PatchPrimaryKey& key) {
160 assert(key.is_sane());
161 return (*(--_patch_map.find(key))).second;
164 boost::shared_ptr<Patch> next_patch(PatchPrimaryKey& key) {
165 assert(key.is_sane());
166 return (*(++_patch_map.find(key))).second;
169 XMLNode& get_state (void);
170 int set_state (const XMLNode& a_node);
174 AvailableForChannels _available_for_channels;
175 PatchBanks _patch_banks;
179 class Note : public PBD::Stateful
183 Note(string a_number, string a_name) : _number(a_number), _name(a_name) {};
186 const string& name() const { return _name; }
187 void set_name(const string a_name) { _name = a_name; }
189 const string& number() const { return _number; }
190 void set_number(const string a_number) { _number = a_number; }
192 XMLNode& get_state (void);
193 int set_state (const XMLNode& a_node);
200 class NoteNameList : public PBD::Stateful
203 typedef std::list<boost::shared_ptr<Note> > Notes;
205 NoteNameList(string a_name) : _name(a_name) {};
208 const string& name() const { return _name; }
209 void set_name(const string a_name) { _name = a_name; }
211 const Notes& notes() const { return _notes; }
213 XMLNode& get_state (void);
214 int set_state (const XMLNode& a_node);
221 class CustomDeviceMode : public PBD::Stateful
224 CustomDeviceMode() {};
225 virtual ~CustomDeviceMode() {};
227 const string& name() const { return _name; }
228 void set_name(const string a_name) { _name = a_name; }
231 XMLNode& get_state (void);
232 int set_state (const XMLNode& a_node);
234 string channel_name_set_name_by_channel(uint8_t channel) {
235 assert(channel <= 15);
236 return _channel_name_set_assignments[channel];
240 /// array index = channel number
241 /// string contents = name of channel name set
243 string _channel_name_set_assignments[16];
246 class MasterDeviceNames : public PBD::Stateful
249 typedef std::list<std::string> Models;
250 /// maps name to CustomDeviceMode
251 typedef std::map<std::string, boost::shared_ptr<CustomDeviceMode> > CustomDeviceModes;
252 typedef std::list<std::string> CustomDeviceModeNames;
253 /// maps name to ChannelNameSet
254 typedef std::map<std::string, boost::shared_ptr<ChannelNameSet> > ChannelNameSets;
255 typedef std::list<boost::shared_ptr<NoteNameList> > NoteNameLists;
258 MasterDeviceNames() {};
259 virtual ~MasterDeviceNames() {};
261 const string& manufacturer() const { return _manufacturer; }
262 void set_manufacturer(const string a_manufacturer) { _manufacturer = a_manufacturer; }
264 const Models& models() const { return _models; }
265 void set_models(const Models some_models) { _models = some_models; }
267 const CustomDeviceModeNames& custom_device_mode_names() const { return _custom_device_mode_names; }
269 boost::shared_ptr<CustomDeviceMode> custom_device_mode_by_name(string mode_name) {
270 assert(mode_name != "");
271 return _custom_device_modes[mode_name];
274 boost::shared_ptr<ChannelNameSet> channel_name_set_by_device_mode_and_channel(string mode, uint8_t channel) {
275 return _channel_name_sets[custom_device_mode_by_name(mode)->channel_name_set_name_by_channel(channel)];
278 boost::shared_ptr<Patch> find_patch(string mode, uint8_t channel, PatchPrimaryKey& key) {
279 return channel_name_set_by_device_mode_and_channel(mode, channel)->find_patch(key);
282 XMLNode& get_state (void);
283 int set_state (const XMLNode& a_node);
286 string _manufacturer;
288 CustomDeviceModes _custom_device_modes;
289 CustomDeviceModeNames _custom_device_mode_names;
290 ChannelNameSets _channel_name_sets;
291 NoteNameLists _note_name_lists;
294 class MIDINameDocument : public PBD::Stateful
297 // Maps Model names to MasterDeviceNames
298 typedef std::map<std::string, boost::shared_ptr<MasterDeviceNames> > MasterDeviceNamesList;
300 MIDINameDocument() {};
301 MIDINameDocument(const string &filename) : _document(XMLTree(filename)) { set_state(*_document.root()); };
302 virtual ~MIDINameDocument() {};
304 const string& author() const { return _author; }
305 void set_author(const string an_author) { _author = an_author; }
307 const MasterDeviceNamesList& master_device_names_by_model() const { return _master_device_names_list; }
309 const MasterDeviceNames::Models& all_models() const { return _all_models; }
311 XMLNode& get_state (void);
312 int set_state (const XMLNode& a_node);
316 MasterDeviceNamesList _master_device_names_list;
318 MasterDeviceNames::Models _all_models;
324 #endif /*MIDNAM_PATCH_H_*/