* make patch selection appear only when there are patches loaded
* add combobox to select CustomDeviceMode * add code to resolve patch names by their msb, lsb and program change number git-svn-id: svn://localhost/ardour2/branches/3.0@4306 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
f8480d6392
commit
dfed4965b7
|
@ -140,11 +140,11 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
|
|||
_view->attach ();
|
||||
}
|
||||
|
||||
// add channel selector expander
|
||||
HBox* midi_controls_hbox = manage(new HBox());
|
||||
|
||||
// Instrument patch selector
|
||||
ComboBoxText* model_selector = manage(new ComboBoxText());
|
||||
ComboBoxText* model_selector = manage(new ComboBoxText());
|
||||
ComboBoxText* custom_device_mode_selector = manage(new ComboBoxText());
|
||||
|
||||
MIDI::Name::MidiPatchManager& patch_manager = MIDI::Name::MidiPatchManager::instance();
|
||||
|
||||
|
@ -154,10 +154,25 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
|
|||
model_selector->append_text(model->c_str());
|
||||
}
|
||||
|
||||
// TODO: persist the choice
|
||||
model_selector->set_active(0);
|
||||
|
||||
std::list<std::string> device_modes = patch_manager.custom_device_mode_names_by_model(model_selector->get_active_text());
|
||||
|
||||
for (std::list<std::string>::const_iterator i = device_modes.begin(); i != device_modes.end(); ++i) {
|
||||
cerr << "found custom device mode " << *i << endl;
|
||||
custom_device_mode_selector->append_text(*i);
|
||||
}
|
||||
|
||||
// TODO: persist the choice
|
||||
custom_device_mode_selector->set_active(0);
|
||||
|
||||
midi_controls_hbox->pack_start(_channel_selector, true, false);
|
||||
_midi_controls_box.pack_start(*model_selector, true, false);
|
||||
if (!patch_manager.all_models().empty()) {
|
||||
_midi_controls_box.pack_start(*model_selector, true, false);
|
||||
_midi_controls_box.pack_start(*custom_device_mode_selector, true, false);
|
||||
}
|
||||
|
||||
_midi_controls_box.pack_start(*midi_controls_hbox, true, true);
|
||||
|
||||
controls_vbox.pack_start(_midi_controls_box, false, false);
|
||||
|
|
|
@ -63,6 +63,14 @@ public:
|
|||
boost::shared_ptr<MasterDeviceNames> master_device_by_model(std::string model_name)
|
||||
{ return _master_devices_by_model[model_name]; }
|
||||
|
||||
std::list<string> custom_device_mode_names_by_model(std::string model_name) {
|
||||
if (model_name != "") {
|
||||
return master_device_by_model(model_name)->custom_device_mode_names();
|
||||
} else {
|
||||
return std::list<string>();
|
||||
}
|
||||
}
|
||||
|
||||
const MasterDeviceNames::Models& all_models() const { return _all_models; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -36,6 +36,46 @@ namespace MIDI
|
|||
namespace Name
|
||||
{
|
||||
|
||||
struct PatchPrimaryKey
|
||||
{
|
||||
public:
|
||||
int msb;
|
||||
int lsb;
|
||||
int program_number;
|
||||
|
||||
PatchPrimaryKey(int a_msb = -1, int a_lsb = -1, int a_program_number = -1) {
|
||||
msb = a_msb;
|
||||
lsb = a_lsb;
|
||||
program_number = a_program_number;
|
||||
}
|
||||
|
||||
bool is_sane() {
|
||||
return
|
||||
0 <= msb <= 127 &&
|
||||
0 <= lsb <= 127 &&
|
||||
0 <= program_number <= 127;
|
||||
}
|
||||
|
||||
inline bool operator==(const PatchPrimaryKey& id) const {
|
||||
return (msb == id.msb && lsb == id.lsb && program_number == id.program_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* obey strict weak ordering or crash in STL containers
|
||||
*/
|
||||
inline bool operator<(const PatchPrimaryKey& id) const {
|
||||
if (msb < id.msb) {
|
||||
return true;
|
||||
} else if (msb == id.msb && lsb < id.lsb) {
|
||||
return true;
|
||||
} else if (lsb == id.lsb && program_number < id.program_number) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Patch : public PBD::Stateful
|
||||
{
|
||||
public:
|
||||
|
@ -52,13 +92,16 @@ public:
|
|||
void set_number(const string a_number) { _number = a_number; }
|
||||
|
||||
const PatchMidiCommands& patch_midi_commands() const { return _patch_midi_commands; }
|
||||
|
||||
const PatchPrimaryKey& patch_primary_key() const { return _id; }
|
||||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode& a_node);
|
||||
|
||||
private:
|
||||
string _number;
|
||||
string _name;
|
||||
string _number;
|
||||
string _name;
|
||||
PatchPrimaryKey _id;
|
||||
PatchMidiCommands _patch_midi_commands;
|
||||
};
|
||||
|
||||
|
@ -89,6 +132,7 @@ class ChannelNameSet : public PBD::Stateful
|
|||
public:
|
||||
typedef std::set<uint8_t> AvailableForChannels;
|
||||
typedef std::list<PatchBank> PatchBanks;
|
||||
typedef std::map<PatchPrimaryKey, Patch> PatchMap;
|
||||
|
||||
ChannelNameSet() {};
|
||||
virtual ~ChannelNameSet() {};
|
||||
|
@ -97,8 +141,14 @@ public:
|
|||
const string& name() const { return _name; }
|
||||
void set_name(const string a_name) { _name = a_name; }
|
||||
|
||||
const AvailableForChannels& available_for_channels() const { return _available_for_channels; }
|
||||
const PatchBanks& patch_banks() const { return _patch_banks; }
|
||||
bool available_for_channel(uint8_t channel) const {
|
||||
return _available_for_channels.find(channel) != _available_for_channels.end();
|
||||
}
|
||||
|
||||
Patch& find_patch(uint8_t msb, uint8_t lsb, uint8_t program_number) {
|
||||
PatchPrimaryKey key(msb, lsb, program_number);
|
||||
return _patch_map[key];
|
||||
}
|
||||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode& a_node);
|
||||
|
@ -107,6 +157,7 @@ private:
|
|||
string _name;
|
||||
AvailableForChannels _available_for_channels;
|
||||
PatchBanks _patch_banks;
|
||||
PatchMap _patch_map;
|
||||
};
|
||||
|
||||
class Note : public PBD::Stateful
|
||||
|
@ -164,6 +215,11 @@ public:
|
|||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode& a_node);
|
||||
|
||||
string channel_name_set_name_by_channel(uint8_t channel) {
|
||||
assert(channel <= 15);
|
||||
return _channel_name_set_assignments[channel];
|
||||
}
|
||||
|
||||
private:
|
||||
/// array index = channel number
|
||||
/// string contents = name of channel name set
|
||||
|
@ -174,10 +230,13 @@ private:
|
|||
class MasterDeviceNames : public PBD::Stateful
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::string> Models;
|
||||
typedef std::list<CustomDeviceMode> CustomDeviceModes;
|
||||
typedef std::list<ChannelNameSet> ChannelNameSets;
|
||||
typedef std::list<NoteNameList> NoteNameLists;
|
||||
typedef std::list<std::string> Models;
|
||||
/// maps name to CustomDeviceMode
|
||||
typedef std::map<std::string, CustomDeviceMode> CustomDeviceModes;
|
||||
typedef std::list<std::string> CustomDeviceModeNames;
|
||||
/// maps name to ChannelNameSet
|
||||
typedef std::map<std::string, ChannelNameSet> ChannelNameSets;
|
||||
typedef std::list<NoteNameList> NoteNameLists;
|
||||
|
||||
|
||||
MasterDeviceNames() {};
|
||||
|
@ -189,15 +248,31 @@ public:
|
|||
const Models& models() const { return _models; }
|
||||
void set_models(const Models some_models) { _models = some_models; }
|
||||
|
||||
const CustomDeviceModeNames& custom_device_mode_names() const { return _custom_device_mode_names; }
|
||||
|
||||
CustomDeviceMode& custom_device_mode_by_name(string& mode_name) {
|
||||
assert(mode_name != "");
|
||||
return _custom_device_modes[mode_name];
|
||||
}
|
||||
|
||||
ChannelNameSet& channel_name_set_by_device_mode_and_channel(string mode, uint8_t channel) {
|
||||
return _channel_name_sets[custom_device_mode_by_name(mode).channel_name_set_name_by_channel(channel)];
|
||||
}
|
||||
|
||||
Patch& find_patch(string mode, uint8_t channel, uint8_t msb, uint8_t lsb, uint8_t program_number) {
|
||||
return channel_name_set_by_device_mode_and_channel(mode, channel).find_patch(msb, lsb, program_number);
|
||||
}
|
||||
|
||||
XMLNode& get_state (void);
|
||||
int set_state (const XMLNode& a_node);
|
||||
|
||||
private:
|
||||
string _manufacturer;
|
||||
Models _models;
|
||||
CustomDeviceModes _custom_device_modes;
|
||||
ChannelNameSets _channel_name_sets;
|
||||
NoteNameLists _note_name_lists;
|
||||
string _manufacturer;
|
||||
Models _models;
|
||||
CustomDeviceModes _custom_device_modes;
|
||||
CustomDeviceModeNames _custom_device_mode_names;
|
||||
ChannelNameSets _channel_name_sets;
|
||||
NoteNameLists _note_name_lists;
|
||||
};
|
||||
|
||||
class MIDINameDocument : public PBD::Stateful
|
||||
|
@ -216,7 +291,7 @@ public:
|
|||
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);
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#include "midi++/midnam_patch.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "midi++/midnam_patch.h"
|
||||
#include "pbd/convert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MIDI
|
||||
|
@ -58,8 +59,27 @@ Patch::set_state (const XMLNode& node)
|
|||
const XMLNodeList events = commands->children();
|
||||
for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
|
||||
_patch_midi_commands.push_back(*(new Evoral::MIDIEvent(*(*i))));
|
||||
XMLNode* node = *i;
|
||||
if (node->name() == "ControlChange") {
|
||||
string control = node->property("Control")->value();
|
||||
assert(control != "");
|
||||
string value = node->property("Value")->value();
|
||||
assert(value != "");
|
||||
|
||||
if (control == "0") {
|
||||
_id.msb = PBD::atoi(value);
|
||||
} else if (control == "32") {
|
||||
_id.lsb = PBD::atoi(value);
|
||||
}
|
||||
} else if (node->name() == "ProgramChange") {
|
||||
string number = node->property("Number")->value();
|
||||
assert(number != "");
|
||||
_id.program_number = PBD::atoi(number);
|
||||
}
|
||||
}
|
||||
|
||||
assert(_id.is_sane());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -204,6 +224,12 @@ ChannelNameSet::set_state (const XMLNode& node)
|
|||
PatchBank* bank = new PatchBank();
|
||||
bank->set_state(*node);
|
||||
_patch_banks.push_back(*bank);
|
||||
const PatchBank::PatchNameList& patches = bank->patch_name_list();
|
||||
for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
|
||||
patch != patches.end();
|
||||
++patch) {
|
||||
_patch_map[patch->patch_primary_key()] = *patch;
|
||||
}
|
||||
// cerr << "after PatchBank pushback" << endl;
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +243,9 @@ int
|
|||
CustomDeviceMode::set_state(const XMLNode& a_node)
|
||||
{
|
||||
assert(a_node.name() == "CustomDeviceMode");
|
||||
|
||||
_name = a_node.property("Name")->value();
|
||||
|
||||
boost::shared_ptr<XMLSharedNodeList> channel_name_set_assignments =
|
||||
a_node.find("//ChannelNameSetAssign");
|
||||
for(XMLSharedNodeList::const_iterator i = channel_name_set_assignments->begin();
|
||||
|
@ -278,7 +307,9 @@ MasterDeviceNames::set_state(const XMLNode& a_node)
|
|||
++i) {
|
||||
CustomDeviceMode* custom_device_mode = new CustomDeviceMode();
|
||||
custom_device_mode->set_state(*(*i));
|
||||
_custom_device_modes.push_back(*custom_device_mode);
|
||||
|
||||
_custom_device_modes[custom_device_mode->name()] = *custom_device_mode;
|
||||
_custom_device_mode_names.push_back(custom_device_mode->name());
|
||||
}
|
||||
|
||||
// cerr << "MasterDeviceNames::set_state ChannelNameSets" << endl;
|
||||
|
@ -290,7 +321,7 @@ MasterDeviceNames::set_state(const XMLNode& a_node)
|
|||
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);
|
||||
_channel_name_sets[channel_name_set->name()] = *channel_name_set;
|
||||
}
|
||||
|
||||
// cerr << "MasterDeviceNames::set_state NoteNameLists" << endl;
|
||||
|
@ -348,14 +379,6 @@ MIDINameDocument::set_state(const XMLNode& a_node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
const MasterDeviceNames::Models&
|
||||
MIDINameDocument::models(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
*/
|
||||
|
||||
XMLNode&
|
||||
MIDINameDocument::get_state(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user