* first working prototype of selecting instruments in the MIDI track header
authorHans Baier <hansfbaier@googlemail.com>
Tue, 9 Dec 2008 07:42:19 +0000 (07:42 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Tue, 9 Dec 2008 07:42:19 +0000 (07:42 +0000)
* parsing patchfiles works

git-svn-id: svn://localhost/ardour2/branches/3.0@4304 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/midi_patch_manager.cc
gtk2_ardour/midi_patch_manager.h
gtk2_ardour/midi_time_axis.cc
libs/ardour/ardour/directory_names.h
libs/ardour/session_directory.cc
libs/midi++2/midi++/midnam_patch.h
libs/midi++2/midnam_patch.cc

index 738441b63120a963b2f078deaab5c63790217149..18e1d5051e4396f11c25e119c440f7cb5f6eef6a 100644 (file)
@@ -52,9 +52,12 @@ MidiPatchManager::refresh()
        
        path path_to_patches = _session->session_directory().midi_patch_path();
        
+       cerr << "Path to patches: " << path_to_patches.to_string() << endl;
+       
        if(!exists(path_to_patches)) {
                return;
        }
+       cerr << "Path to patches: " << path_to_patches.to_string() << " exists" << endl;
        
        assert(is_directory(path_to_patches));
        
@@ -62,10 +65,29 @@ MidiPatchManager::refresh()
        vector<path> result;
        
        find_matching_files_in_directory(path_to_patches, pattern, result);
+
+       cerr << "patchfiles result contains " << result.size() << " elements" << endl;
        
        for(vector<path>::iterator i = result.begin(); i != result.end(); ++i) {
+               cerr << "processing patchfile " << i->to_string() << endl;      
+               
                boost::shared_ptr<MIDINameDocument> document(new MIDINameDocument(i->to_string()));
-               _documents.push_back(document);
+               for(MIDINameDocument::MasterDeviceNamesList::const_iterator device = 
+                         document->master_device_names_by_model().begin();
+                   device != document->master_device_names_by_model().end();
+                   ++device) {
+                       cerr << "got model " << device->first << endl;
+                       // have access to the documents by model name
+                       _documents[device->first] = document;
+                       // build a list of all master devices from all documents
+                       _master_devices_by_model[device->first] = device->second;
+                       _all_models.push_back(device->first);
+                       
+                       // make sure there are no double model names
+                       // TODO: handle this gracefully.
+                       assert(_documents.count(device->first) == 1);
+                       assert(_master_devices_by_model.count(device->first) == 1);
+               }
        }
 }
 
index ec82e932a8529e0dc3c1e270fcc100a5ff34536f..f971663d4d2ffb0a9ce3c538ed4bdc9cca73d764 100644 (file)
@@ -44,7 +44,7 @@ private:
        static MidiPatchManager* _manager; 
        
 public:
-       typedef std::list<boost::shared_ptr<MIDINameDocument> > MidiNameDocuments;
+       typedef std::map<std::string, boost::shared_ptr<MIDINameDocument> > MidiNameDocuments;
        
        virtual ~MidiPatchManager() { _manager = 0; }
        
@@ -57,12 +57,22 @@ public:
        
        void set_session (ARDOUR::Session&);
        
+       boost::shared_ptr<MIDINameDocument> document_by_model(std::string model_name) 
+               { return _documents[model_name]; }
+       
+       boost::shared_ptr<MasterDeviceNames> master_device_by_model(std::string model_name) 
+               { return _master_devices_by_model[model_name]; }
+       
+       const MasterDeviceNames::Models& all_models() const { return _all_models; }
+       
 private:
        void drop_session();
        void refresh();
        
-       ARDOUR::Session*  _session;
-       MidiNameDocuments _documents;
+       ARDOUR::Session*                        _session;
+       MidiNameDocuments                       _documents;
+       MIDINameDocument::MasterDeviceNamesList _master_devices_by_model;
+       MasterDeviceNames::Models               _all_models;
 };
 
 } // namespace Name
index 01505ad3033a521868f7baa76b959718ca651b53..1c6ac5b5fe9e62db5fc96e00a4e0c8f21a1d0b2d 100644 (file)
@@ -68,6 +68,7 @@
 #include "midi_streamview.h"
 #include "utils.h"
 #include "midi_scroomer.h"
+#include "midi_patch_manager.h"
 #include "piano_roll_header.h"
 #include "ghostregion.h"
 
@@ -141,9 +142,27 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
        }
                
        // add channel selector expander
-       HBox *midi_expander_box = manage(new HBox());
-       midi_expander_box->pack_start(_channel_selector, false, false);
-       _midi_expander.add(*midi_expander_box);
+       HBox* midi_expander_hbox = manage(new HBox());
+       VBox* midi_expander_vbox = manage(new VBox());
+       
+       // Instrument patch selector
+       ComboBoxText*       model_selector = manage(new ComboBoxText());
+       
+       MIDI::Name::MidiPatchManager& patch_manager = MIDI::Name::MidiPatchManager::instance();
+       patch_manager.set_session(session());
+
+       for (MIDI::Name::MasterDeviceNames::Models::const_iterator model = patch_manager.all_models().begin();
+            model != patch_manager.all_models().end();
+            ++model) {
+               model_selector->append_text(model->c_str());
+       }
+       
+       model_selector->set_active(0);
+       
+       midi_expander_hbox->pack_start(_channel_selector, true, false);
+       midi_expander_vbox->pack_start(*model_selector, true, false);
+       midi_expander_vbox->pack_start(*midi_expander_hbox, true, true);
+       _midi_expander.add(*midi_expander_vbox);
        _midi_expander.property_expanded().signal_changed().connect(
                        mem_fun(this, &MidiTimeAxisView::channel_selector_toggled));
        controls_vbox.pack_start(_midi_expander, false, false);
index 8fabe025d12095871af1acd2abe830062ef9db76..2f9991fd650ced01d45a97acd45eaf2279dc6046 100644 (file)
@@ -9,6 +9,7 @@ namespace ARDOUR {
 extern const char* const old_sound_dir_name;
 extern const char* const sound_dir_name;
 extern const char* const midi_dir_name;
+extern const char* const midi_patch_dir_name;
 extern const char* const dead_sound_dir_name;
 extern const char* const dead_midi_dir_name;
 extern const char* const interchange_dir_name;
index 50e213a4c2d90b07c1113725f964628d010776dc..299f5423161aa634c6bcbe9cbddf1909c9896122 100644 (file)
@@ -109,7 +109,7 @@ SessionDirectory::midi_path () const
 const path
 SessionDirectory::midi_patch_path () const
 {
-       return sources_root() / midi_patch_path();
+       return sources_root() / midi_patch_dir_name;
 }
 
 const path
index 2561d905eb3367f73d5521ad50de9e96c58d605b..f9616ecf2df8bed726f2826cfd704e217af260e1 100644 (file)
@@ -24,6 +24,7 @@
 #include <string>
 #include <list>
 #include <set>
+#include <map>
 
 #include "pbd/stateful.h"
 #include "midi++/event.h"
@@ -202,7 +203,8 @@ private:
 class MIDINameDocument : public PBD::Stateful
 {
 public:
-       typedef std::list<MasterDeviceNames> MasterDeviceNamesList;
+       // Maps Model names to MasterDeviceNames
+       typedef std::map<std::string, boost::shared_ptr<MasterDeviceNames> > MasterDeviceNamesList;
        
        MIDINameDocument() {};
        MIDINameDocument(const string &filename) : _document(XMLTree(filename)) { set_state(*_document.root()); };
@@ -211,13 +213,18 @@ public:
        const string& author() const { return _author; }
        void set_author(const string an_author) { _author = an_author; }
        
+       const MasterDeviceNamesList& master_device_names_by_model() const { return _master_device_names_list; }
+       
+       const MasterDeviceNames::Models& all_models() const { return _all_models; }
+       
        XMLNode& get_state (void);
        int      set_state (const XMLNode& a_node);
 
 private:
-       string                _author;
-       MasterDeviceNamesList _master_device_names_list;
-       XMLTree               _document;
+       string                        _author;
+       MasterDeviceNamesList         _master_device_names_list;
+       XMLTree                       _document;
+       MasterDeviceNames::Models     _all_models;
 };
 
 }
index 56b36b5919777adc2ac16c096a99cb73d5bd4806..c23901d7213ebb4ba66d9a9a6abb3d678b2349c7 100644 (file)
 #include "midi++/midnam_patch.h"
 #include <algorithm>
 
+#include <iostream>
+
+using namespace std;
+
 namespace MIDI
 {
 
@@ -97,9 +101,9 @@ NoteNameList::set_state (const XMLNode& node)
        boost::shared_ptr<XMLSharedNodeList> notes =
                                        node.find("//Note");
        for (XMLSharedNodeList::const_iterator i = notes->begin(); i != notes->end(); ++i) {
-               Note note;
-               note.set_state(*(*i));
-               _notes.push_back(note);
+               Note* note = new Note();
+               note->set_state(*(*i));
+               _notes.push_back(*note);
        }
        
        return 0;
@@ -130,9 +134,9 @@ PatchBank::set_state (const XMLNode& node)
        assert(patch_name_list);
        const XMLNodeList patches = patch_name_list->children();
        for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
-               Patch patch;
-               patch.set_state(*(*i));
-               _patch_name_list.push_back(patch);
+               Patch* patch = new Patch();
+               patch->set_state(*(*i));
+               _patch_name_list.push_back(*patch);
        }
 
        return 0;
@@ -174,26 +178,37 @@ ChannelNameSet::set_state (const XMLNode& node)
 {
        assert(node.name() == "ChannelNameSet");
        _name   = node.property("Name")->value();
+       // cerr << "ChannelNameSet _name: " << _name << endl;
        const XMLNodeList children = node.children();
        for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
                XMLNode* node = *i;
                assert(node);
                if (node->name() == "AvailableForChannels") {
+                       // cerr << "AvailableForChannels" << endl;
                        boost::shared_ptr<XMLSharedNodeList> channels =
                                node->find("//AvailableChannel[@Available = 'true']/@Channel");
+                       // cerr << "AvailableForChannels after find" << endl;
                        for(XMLSharedNodeList::const_iterator i = channels->begin();
                            i != channels->end();
                            ++i) {
+                               // cerr << "AvailableForChannels before insert" << endl;
                                _available_for_channels.insert(atoi((*i)->attribute_value().c_str()));
+                               // cerr << "AvailableForChannels after insert" << endl;
                        }
                }
+               
+               // cerr << "before PatchBank" << endl;
 
                if (node->name() == "PatchBank") {
-                       PatchBank bank;
-                       bank.set_state(*node);
-                       _patch_banks.push_back(bank);
+                       // cerr << "got PatchBank" << endl;
+                       PatchBank* bank = new PatchBank();
+                       bank->set_state(*node);
+                       _patch_banks.push_back(*bank);
+                       // cerr << "after PatchBank pushback" << endl;
                }
        }
+       
+       // cerr << "ChannelnameSet done" << endl;
 
        return 0;
 }
@@ -201,7 +216,7 @@ ChannelNameSet::set_state (const XMLNode& node)
 int
 CustomDeviceMode::set_state(const XMLNode& a_node)
 {
-       assert(a_node.name() == "CustomDeviceNode");
+       assert(a_node.name() == "CustomDeviceMode");
        boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
                a_node.find("//ChannelNameSetAssign");
        for(XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
@@ -235,48 +250,58 @@ CustomDeviceMode::get_state(void)
 int
 MasterDeviceNames::set_state(const XMLNode& a_node)
 {
+       // cerr << "MasterDeviceNames::set_state Manufacturer" << endl;
        // Manufacturer
        boost::shared_ptr<XMLSharedNodeList> manufacturer = a_node.find("//Manufacturer");
        assert(manufacturer->size() == 1);
        _manufacturer = manufacturer->front()->content();
 
+       // cerr << "MasterDeviceNames::set_state models" << endl;
        // Models
        boost::shared_ptr<XMLSharedNodeList> models = a_node.find("//Model");
        assert(models->size() >= 1);
        for (XMLSharedNodeList::iterator i = models->begin();
             i != models->end();
             ++i) {
-               _models.push_back((*i)->content());
+               const XMLNodeList& contents = (*i)->children();
+               assert(contents.size() == 1);
+               XMLNode * content = *(contents.begin());
+               assert(content->is_content());
+               _models.push_back(content->content());
        }
 
+       // cerr << "MasterDeviceNames::set_state CustomDeviceModes" << endl;
        // CustomDeviceModes
        boost::shared_ptr<XMLSharedNodeList> custom_device_modes = a_node.find("//CustomDeviceMode");
        for (XMLSharedNodeList::iterator i = custom_device_modes->begin();
             i != custom_device_modes->end();
             ++i) {
-               CustomDeviceMode custom_device_mode;
-               custom_device_mode.set_state(*(*i));
-               _custom_device_modes.push_back(custom_device_mode);
+               CustomDeviceMode* custom_device_mode = new CustomDeviceMode();
+               custom_device_mode->set_state(*(*i));
+               _custom_device_modes.push_back(*custom_device_mode);
        }
 
+       // cerr << "MasterDeviceNames::set_state ChannelNameSets" << endl;
        // ChannelNameSets
        boost::shared_ptr<XMLSharedNodeList> channel_name_sets = a_node.find("//ChannelNameSet");
        for (XMLSharedNodeList::iterator i = channel_name_sets->begin();
             i != channel_name_sets->end();
             ++i) {
-               ChannelNameSet channel_name_set;
-               channel_name_set.set_state(*(*i));
-               _channel_name_sets.push_back(channel_name_set);
+               ChannelNameSet* channel_name_set = new ChannelNameSet();
+               // cerr << "MasterDeviceNames::set_state ChannelNameSet before set_state" << endl;
+               channel_name_set->set_state(*(*i));
+               _channel_name_sets.push_back(*channel_name_set);
        }
 
+       // cerr << "MasterDeviceNames::set_state NoteNameLists" << endl;
        // NoteNameLists
        boost::shared_ptr<XMLSharedNodeList> note_name_lists = a_node.find("//NoteNameList");
        for (XMLSharedNodeList::iterator i = note_name_lists->begin();
             i != note_name_lists->end();
             ++i) {
-               NoteNameList note_name_list;
-               note_name_list.set_state(*(*i));
-               _note_name_lists.push_back(note_name_list);
+               NoteNameList* note_name_list = new NoteNameList();
+               note_name_list->set_state(*(*i));
+               _note_name_lists.push_back(*note_name_list);
        }
 
        return 0;
@@ -297,19 +322,40 @@ MIDINameDocument::set_state(const XMLNode& a_node)
        assert(author->size() == 1);
        _author = author->front()->content();
        
+       // cerr << "MIDINameDocument::set_state befor masterdevicenames" << endl;
        // MasterDeviceNames
        boost::shared_ptr<XMLSharedNodeList> master_device_names_list = a_node.find("//MasterDeviceNames");
        for (XMLSharedNodeList::iterator i = master_device_names_list->begin();
             i != master_device_names_list->end();
             ++i) {
-               MasterDeviceNames master_device_names;
-               master_device_names.set_state(*(*i));
-               _master_device_names_list.push_back(master_device_names);
+               boost::shared_ptr<MasterDeviceNames> master_device_names(new MasterDeviceNames());
+               // cerr << "MIDINameDocument::set_state before masterdevicenames->set_state" << endl;
+               master_device_names->set_state(*(*i));
+               // cerr << "MIDINameDocument::set_state after masterdevicenames->set_state" << endl;
+               
+               for (MasterDeviceNames::Models::const_iterator model = master_device_names->models().begin();
+                    model != master_device_names->models().end();
+                    ++model) {
+                       // cerr << "MIDINameDocument::set_state inserting model " << *model << endl;
+                               _master_device_names_list.insert(
+                                               std::pair<std::string, boost::shared_ptr<MasterDeviceNames> >
+                                                        (*model,      master_device_names));
+                               
+                               _all_models.push_back(*model);
+               }
        }
        
        return 0;
 }
 
+/*
+const MasterDeviceNames::Models&
+MIDINameDocument::models(void)
+{
+       ;
+}
+*/
+
 XMLNode&
 MIDINameDocument::get_state(void)
 {