+boost::shared_ptr<const ValueNameList>
+MasterDeviceNames::value_name_list_by_control(const std::string& mode, uint8_t channel, uint8_t number)
+{
+ boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(mode, channel);
+ if (!chan_names) {
+ return boost::shared_ptr<const ValueNameList>();
+ }
+
+ boost::shared_ptr<ControlNameList> control_names = control_name_list(chan_names->control_list_name());
+ if (!control_names) {
+ return boost::shared_ptr<const ValueNameList>();
+ }
+
+ boost::shared_ptr<const Control> control = control_names->control(number);
+ if (!control) {
+ return boost::shared_ptr<const ValueNameList>();
+ }
+
+ if (!control->value_name_list_name().empty()) {
+ return value_name_list(control->value_name_list_name());
+ } else {
+ return control->value_name_list();
+ }
+}
+
+boost::shared_ptr<CustomDeviceMode>
+MasterDeviceNames::custom_device_mode_by_name(const std::string& mode_name)
+{
+ return _custom_device_modes[mode_name];
+}
+
+boost::shared_ptr<ChannelNameSet>
+MasterDeviceNames::channel_name_set_by_channel(const std::string& mode, uint8_t channel)
+{
+ boost::shared_ptr<CustomDeviceMode> cdm = custom_device_mode_by_name(mode);
+ boost::shared_ptr<ChannelNameSet> cns = _channel_name_sets[cdm->channel_name_set_name_by_channel(channel)];
+ return cns;
+}
+
+boost::shared_ptr<Patch>
+MasterDeviceNames::find_patch(const std::string& mode, uint8_t channel, const PatchPrimaryKey& key)
+{
+ boost::shared_ptr<ChannelNameSet> cns = channel_name_set_by_channel(mode, channel);
+ if (!cns) return boost::shared_ptr<Patch>();
+ return cns->find_patch(key);
+}
+
+boost::shared_ptr<ChannelNameSet>
+MasterDeviceNames::channel_name_set(const std::string& name)
+{
+ ChannelNameSets::const_iterator i = _channel_name_sets.find(name);
+ if (i != _channel_name_sets.end()) {
+ return i->second;
+ }
+ return boost::shared_ptr<ChannelNameSet>();
+}
+
+boost::shared_ptr<ControlNameList>
+MasterDeviceNames::control_name_list(const std::string& name)
+{
+ ControlNameLists::const_iterator i = _control_name_lists.find(name);
+ if (i != _control_name_lists.end()) {
+ return i->second;
+ }
+ return boost::shared_ptr<ControlNameList>();
+}
+
+boost::shared_ptr<ValueNameList>
+MasterDeviceNames::value_name_list(const std::string& name)
+{
+ ValueNameLists::const_iterator i = _value_name_lists.find(name);
+ if (i != _value_name_lists.end()) {
+ return i->second;
+ }
+ return boost::shared_ptr<ValueNameList>();
+}
+
+boost::shared_ptr<NoteNameList>
+MasterDeviceNames::note_name_list(const std::string& name)
+{
+ NoteNameLists::const_iterator i = _note_name_lists.find(name);
+ if (i != _note_name_lists.end()) {
+ return i->second;
+ }
+ return boost::shared_ptr<NoteNameList>();
+}
+
+std::string
+MasterDeviceNames::note_name(const std::string& mode_name,
+ uint8_t channel,
+ uint16_t bank,
+ uint8_t program,
+ uint8_t number)
+{
+ if (number > 127) {
+ return "";
+ }
+
+ boost::shared_ptr<const Patch> patch(
+ find_patch(mode_name, channel, PatchPrimaryKey(program, bank)));
+ if (!patch) {
+ return "";
+ }
+
+ boost::shared_ptr<const NoteNameList> note_names(
+ note_name_list(patch->note_list_name()));
+ if (!note_names) {
+ /* No note names specific to this patch, check the ChannelNameSet */
+ boost::shared_ptr<ChannelNameSet> chan_names = channel_name_set_by_channel(
+ mode_name, channel);
+ if (chan_names) {
+ note_names = note_name_list(chan_names->note_list_name());
+ }
+ }
+ if (!note_names) {
+ return "";
+ }
+
+ boost::shared_ptr<const Note> note(note_names->notes()[number]);
+ return note ? note->name() : "";
+}
+