couple of fixes to enable building, and building with gtkmm 2.2(<4)
[ardour.git] / libs / midi++2 / midi++ / midnam_patch.h
1 /*
2     Copyright (C) 2008 Hans Baier 
3
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.
8
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.
13
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.
17
18     $Id$
19 */
20
21 #ifndef MIDNAM_PATCH_H_
22 #define MIDNAM_PATCH_H_
23
24 #include <iostream>
25 #include <string>
26 #include <list>
27 #include <set>
28 #include <map>
29
30 #include "midi++/event.h"
31 #include "pbd/xml++.h"
32
33 namespace MIDI
34 {
35
36 namespace Name
37 {
38
39 struct PatchPrimaryKey
40 {
41 public:
42         int msb;
43         int lsb;
44         int program_number;
45         
46         PatchPrimaryKey(int a_msb = -1, int a_lsb = -1, int a_program_number = -1) {
47                 msb = a_msb;
48                 lsb = a_lsb;
49                 program_number = a_program_number;
50         }
51         
52         bool is_sane() {        
53                 return ((msb >= 0) && (msb <= 127) &&
54                         (lsb >= 0) && (lsb <= 127) &&
55                         (program_number >=0 ) && (program_number <= 127));
56         }
57         
58         inline PatchPrimaryKey& operator=(const PatchPrimaryKey& id) {
59                 msb = id.msb;
60                 lsb = id.lsb; 
61                 program_number = id.program_number;
62                 return *this;
63         }
64         
65         inline bool operator==(const PatchPrimaryKey& id) const {
66                 return (msb == id.msb && lsb == id.lsb && program_number == id.program_number);
67         }
68         
69         /**
70          * obey strict weak ordering or crash in STL containers
71          */
72         inline bool operator<(const PatchPrimaryKey& id) const {
73                 if (msb < id.msb) {
74                         return true;
75                 } else if (msb == id.msb && lsb < id.lsb) {
76                         return true;
77                 } else if (lsb == id.lsb && program_number < id.program_number) {
78                         return true;
79                 }
80                 
81                 return false;
82         }
83 };
84
85 class PatchBank;
86         
87 class Patch 
88 {
89 public:
90
91         Patch (PatchBank* a_bank = 0);
92         Patch(std::string a_number, std::string a_name, PatchBank* a_bank = 0);
93         virtual ~Patch() {};
94
95         const std::string& name() const          { return _name; }
96         void set_name(const std::string a_name)       { _name = a_name; }
97
98         const std::string& number() const        { return _number; }
99         void set_number(const std::string a_number)   { _number = a_number; }
100         
101         const PatchPrimaryKey&   patch_primary_key()   const { return _id; }
102
103         XMLNode& get_state (void);
104         int      set_state (const XMLTree&, const XMLNode&);
105
106         int use_bank_info (PatchBank*);
107
108 private:
109         std::string        _number;
110         std::string        _name;
111         PatchPrimaryKey   _id;
112 };
113
114 class PatchBank 
115 {
116 public:
117         typedef std::list<boost::shared_ptr<Patch> > PatchNameList;
118
119         PatchBank () : _id(0) {};
120         PatchBank (std::string a_name, PatchPrimaryKey* an_id = 0) : _name(a_name), _id(an_id) {};
121         virtual ~PatchBank() { delete _id; };
122
123         const std::string& name() const               { return _name; }
124         void set_name(const std::string a_name)       { _name = a_name; }
125
126         const PatchNameList& patch_name_list() const { return _patch_name_list; }
127         const std::string& patch_list_name() const { return _patch_list_name; }
128
129         int set_patch_name_list (const PatchNameList&);
130
131         const PatchPrimaryKey* patch_primary_key()  const { return _id; }
132
133         XMLNode& get_state (void);
134         int      set_state (const XMLTree&, const XMLNode&);
135
136 private:
137         std::string       _name;
138         PatchNameList     _patch_name_list;
139         PatchPrimaryKey*  _id;
140         std::string       _patch_list_name;
141 };
142
143 class ChannelNameSet
144 {
145 public:
146         typedef std::set<uint8_t>                                    AvailableForChannels;
147         typedef std::list<boost::shared_ptr<PatchBank> >             PatchBanks;
148         typedef std::map<PatchPrimaryKey, boost::shared_ptr<Patch> > PatchMap;
149         typedef std::list<PatchPrimaryKey>                           PatchList;
150
151         ChannelNameSet() {};
152         virtual ~ChannelNameSet() {};
153         ChannelNameSet(std::string a_name) : _name(a_name) {};
154
155         const std::string& name() const          { return _name; }
156         void set_name(const std::string a_name)  { _name = a_name; }
157         
158         const PatchBanks& patch_banks() const    { return _patch_banks; }
159
160         bool available_for_channel(uint8_t channel) const { 
161                 return _available_for_channels.find(channel) != _available_for_channels.end(); 
162         }
163         
164         boost::shared_ptr<Patch> find_patch(PatchPrimaryKey& key) {
165                 assert(key.is_sane());
166                 return _patch_map[key];
167         }
168         
169         boost::shared_ptr<Patch> previous_patch(PatchPrimaryKey& key) {
170                 assert(key.is_sane());
171                 std::cerr << "finding patch with "  << key.msb << "/" << key.lsb << "/" <<key.program_number << std::endl; 
172                 for (PatchList::const_iterator i = _patch_list.begin();
173                          i != _patch_list.end();
174                          ++i) {
175                         if ((*i) == key) {
176                                 if (i != _patch_list.begin()) {
177                                         std::cerr << "got it!" << std::endl;
178                                         --i;
179                                         return  _patch_map[*i];
180                                 } 
181                         }
182                 }
183                         
184                 return boost::shared_ptr<Patch>();
185         }
186         
187         boost::shared_ptr<Patch> next_patch(PatchPrimaryKey& key) {
188                 assert(key.is_sane());
189                 std::cerr << "finding patch with "  << key.msb << "/" << key.lsb << "/" <<key.program_number << std::endl; 
190                 for (PatchList::const_iterator i = _patch_list.begin();
191                          i != _patch_list.end();
192                          ++i) {
193                         if ((*i) == key) {
194                                 if (++i != _patch_list.end()) {
195                                         std::cerr << "got it!" << std::endl;
196                                         return  _patch_map[*i];
197                                 } else {
198                                         --i;
199                                 }
200                         }
201                 }
202                         
203                 return boost::shared_ptr<Patch>();
204         }
205
206         XMLNode& get_state (void);
207         int      set_state (const XMLTree&, const XMLNode&);
208
209 private:
210         std::string _name;
211         AvailableForChannels _available_for_channels;
212         PatchBanks           _patch_banks;
213         PatchMap             _patch_map;
214         PatchList            _patch_list;
215         std::string          _patch_list_name;
216 };
217
218 class Note
219 {
220 public:
221         Note() {};
222         Note(std::string a_number, std::string a_name) : _number(a_number), _name(a_name) {};
223         ~Note() {};
224
225         const std::string& name() const               { return _name; }
226         void set_name(const std::string a_name)       { _name = a_name; }
227
228         const std::string& number() const             { return _number; }
229         void set_number(const std::string a_number)   { _number = a_number; }
230
231         XMLNode& get_state (void);
232         int      set_state (const XMLTree&, const XMLNode&);
233
234 private:
235         std::string _number;
236         std::string _name;
237 };
238
239 class NoteNameList 
240 {
241 public:
242         typedef std::list<boost::shared_ptr<Note> > Notes;
243         NoteNameList() {};
244         NoteNameList (std::string a_name) : _name(a_name) {};
245         ~NoteNameList() {};
246
247         const std::string& name() const          { return _name; }
248         void set_name(const std::string a_name)       { _name = a_name; }
249
250         const Notes& notes() const { return _notes; }
251
252         XMLNode& get_state (void);
253         int      set_state (const XMLTree&, const XMLNode&);
254
255 private:
256         std::string _name;
257         Notes  _notes;
258 };
259
260 class CustomDeviceMode
261 {
262 public:
263         CustomDeviceMode() {};
264         virtual ~CustomDeviceMode() {};
265
266         const std::string& name() const          { return _name; }
267         void set_name(const std::string a_name)  { _name = a_name; }
268
269         
270         XMLNode& get_state (void);
271         int      set_state (const XMLTree&, const XMLNode&);
272         
273         std::string channel_name_set_name_by_channel(uint8_t channel) {
274                 assert(channel <= 15);
275                 return _channel_name_set_assignments[channel]; 
276         }
277         
278 private:
279         /// array index = channel number
280         /// string contents = name of channel name set 
281         std::string _name;
282         std::string _channel_name_set_assignments[16];
283 };
284
285 class MasterDeviceNames
286 {
287 public:
288         typedef std::list<std::string>                                       Models;
289         /// maps name to CustomDeviceMode
290         typedef std::map<std::string, boost::shared_ptr<CustomDeviceMode> >  CustomDeviceModes;
291         typedef std::list<std::string>                                       CustomDeviceModeNames;
292         /// maps name to ChannelNameSet
293         typedef std::map<std::string, boost::shared_ptr<ChannelNameSet> >    ChannelNameSets;
294         typedef std::list<boost::shared_ptr<NoteNameList> >                  NoteNameLists;
295         typedef std::map<std::string, PatchBank::PatchNameList>              PatchNameLists;
296         
297         MasterDeviceNames() {};
298         virtual ~MasterDeviceNames() {};
299         
300         const std::string& manufacturer() const { return _manufacturer; }
301         void set_manufacturer(const std::string a_manufacturer) { _manufacturer = a_manufacturer; }
302         
303         const Models& models() const { return _models; }
304         void set_models(const Models some_models) { _models = some_models; }
305         
306         const CustomDeviceModeNames& custom_device_mode_names() const { return _custom_device_mode_names; }
307         
308         boost::shared_ptr<CustomDeviceMode> custom_device_mode_by_name(std::string mode_name) {
309                 assert(mode_name != "");
310                 return _custom_device_modes[mode_name];
311         }
312         
313         boost::shared_ptr<ChannelNameSet> channel_name_set_by_device_mode_and_channel(std::string mode, uint8_t channel) {
314                 return _channel_name_sets[custom_device_mode_by_name(mode)->channel_name_set_name_by_channel(channel)];
315         }
316         
317         boost::shared_ptr<Patch> find_patch(std::string mode, uint8_t channel, PatchPrimaryKey& key) {
318                 return channel_name_set_by_device_mode_and_channel(mode, channel)->find_patch(key);
319         }
320         
321         XMLNode& get_state (void);
322         int      set_state (const XMLTree&, const XMLNode&);
323         
324 private:
325         std::string           _manufacturer;
326         Models                _models;
327         CustomDeviceModes     _custom_device_modes;
328         CustomDeviceModeNames _custom_device_mode_names;
329         ChannelNameSets       _channel_name_sets;
330         NoteNameLists         _note_name_lists;
331         PatchNameLists        _patch_name_lists;
332 };
333
334 class MIDINameDocument
335 {
336 public:
337         // Maps Model names to MasterDeviceNames
338         typedef std::map<std::string, boost::shared_ptr<MasterDeviceNames> > MasterDeviceNamesList;
339         
340         MIDINameDocument() {}
341         MIDINameDocument(const std::string &filename);
342         virtual ~MIDINameDocument() {};
343
344         const std::string& author() const { return _author; }
345         void set_author(const std::string an_author) { _author = an_author; }
346         
347         const MasterDeviceNamesList& master_device_names_by_model() const { return _master_device_names_list; }
348         
349         const MasterDeviceNames::Models& all_models() const { return _all_models; }
350                 
351         XMLNode& get_state (void);
352         int      set_state (const XMLTree&, const XMLNode&);
353
354 private:
355         std::string                   _author;
356         MasterDeviceNamesList         _master_device_names_list;
357         XMLTree                       _document;
358         MasterDeviceNames::Models     _all_models;
359 };
360
361 }
362
363 }
364 #endif /*MIDNAM_PATCH_H_*/