From 457f06855e30ebdfeae0a5dfe39cb8f52422a912 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Tue, 9 Dec 2008 07:42:19 +0000 Subject: [PATCH] * first working prototype of selecting instruments in the MIDI track header * parsing patchfiles works git-svn-id: svn://localhost/ardour2/branches/3.0@4304 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/midi_patch_manager.cc | 24 +++++++- gtk2_ardour/midi_patch_manager.h | 16 ++++- gtk2_ardour/midi_time_axis.cc | 25 +++++++- libs/ardour/ardour/directory_names.h | 1 + libs/ardour/session_directory.cc | 2 +- libs/midi++2/midi++/midnam_patch.h | 15 +++-- libs/midi++2/midnam_patch.cc | 92 +++++++++++++++++++++------- 7 files changed, 140 insertions(+), 35 deletions(-) diff --git a/gtk2_ardour/midi_patch_manager.cc b/gtk2_ardour/midi_patch_manager.cc index 738441b631..18e1d5051e 100644 --- a/gtk2_ardour/midi_patch_manager.cc +++ b/gtk2_ardour/midi_patch_manager.cc @@ -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 result; find_matching_files_in_directory(path_to_patches, pattern, result); + + cerr << "patchfiles result contains " << result.size() << " elements" << endl; for(vector::iterator i = result.begin(); i != result.end(); ++i) { + cerr << "processing patchfile " << i->to_string() << endl; + boost::shared_ptr 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); + } } } diff --git a/gtk2_ardour/midi_patch_manager.h b/gtk2_ardour/midi_patch_manager.h index ec82e932a8..f971663d4d 100644 --- a/gtk2_ardour/midi_patch_manager.h +++ b/gtk2_ardour/midi_patch_manager.h @@ -44,7 +44,7 @@ private: static MidiPatchManager* _manager; public: - typedef std::list > MidiNameDocuments; + typedef std::map > MidiNameDocuments; virtual ~MidiPatchManager() { _manager = 0; } @@ -57,12 +57,22 @@ public: void set_session (ARDOUR::Session&); + boost::shared_ptr document_by_model(std::string model_name) + { return _documents[model_name]; } + + boost::shared_ptr 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 diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 01505ad303..1c6ac5b5fe 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -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); diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h index 8fabe025d1..2f9991fd65 100644 --- a/libs/ardour/ardour/directory_names.h +++ b/libs/ardour/ardour/directory_names.h @@ -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; diff --git a/libs/ardour/session_directory.cc b/libs/ardour/session_directory.cc index 50e213a4c2..299f542316 100644 --- a/libs/ardour/session_directory.cc +++ b/libs/ardour/session_directory.cc @@ -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 diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index 2561d905eb..f9616ecf2d 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "pbd/stateful.h" #include "midi++/event.h" @@ -202,7 +203,8 @@ private: class MIDINameDocument : public PBD::Stateful { public: - typedef std::list MasterDeviceNamesList; + // Maps Model names to MasterDeviceNames + typedef std::map > 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; }; } diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc index 56b36b5919..c23901d721 100644 --- a/libs/midi++2/midnam_patch.cc +++ b/libs/midi++2/midnam_patch.cc @@ -21,6 +21,10 @@ #include "midi++/midnam_patch.h" #include +#include + +using namespace std; + namespace MIDI { @@ -97,9 +101,9 @@ NoteNameList::set_state (const XMLNode& node) boost::shared_ptr 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 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 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 manufacturer = a_node.find("//Manufacturer"); assert(manufacturer->size() == 1); _manufacturer = manufacturer->front()->content(); + // cerr << "MasterDeviceNames::set_state models" << endl; // Models boost::shared_ptr 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 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 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 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 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 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 > + (*model, master_device_names)); + + _all_models.push_back(*model); + } } return 0; } +/* +const MasterDeviceNames::Models& +MIDINameDocument::models(void) +{ + ; +} +*/ + XMLNode& MIDINameDocument::get_state(void) { -- 2.30.2