13
0

* extend MIDNAM support (PatchBanks containing the bank select MIDI Commands)

git-svn-id: svn://localhost/ardour2/branches/3.0@4409 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Hans Baier 2009-01-15 03:13:24 +00:00
parent bed58e9f37
commit 625507fc1a
2 changed files with 59 additions and 27 deletions

View File

@ -82,22 +82,24 @@ public:
}
};
class PatchBank;
typedef std::list<boost::shared_ptr<Evoral::MIDIEvent> > PatchMidiCommands;
class Patch : public PBD::Stateful
{
public:
typedef std::list<boost::shared_ptr<Evoral::MIDIEvent> > PatchMidiCommands;
Patch() {};
Patch(string a_number, string a_name) : _number(a_number), _name(a_name) {};
~Patch() {};
Patch(PatchBank* a_bank = 0) : _bank(a_bank) {};
Patch(string a_number, string a_name, PatchBank* a_bank = 0)
: _number(a_number), _name(a_name), _bank(a_bank) {};
virtual ~Patch() {};
const string& name() const { return _name; }
void set_name(const string a_name) { _name = a_name; }
const string& number() const { return _number; }
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; }
@ -107,8 +109,9 @@ public:
private:
string _number;
string _name;
// cannot use a boost::shared_ptr here in order to avoid retain cycles
PatchBank* _bank;
PatchPrimaryKey _id;
PatchMidiCommands _patch_midi_commands;
};
class PatchBank : public PBD::Stateful
@ -116,21 +119,24 @@ class PatchBank : public PBD::Stateful
public:
typedef std::list<boost::shared_ptr<Patch> > PatchNameList;
PatchBank() {};
virtual ~PatchBank() {};
PatchBank(string a_name) : _name(a_name) {};
PatchBank() : _id(0) {};
PatchBank(string a_name, PatchPrimaryKey* an_id = 0) : _name(a_name), _id(an_id) {};
virtual ~PatchBank() { delete _id; };
const string& name() const { return _name; }
void set_name(const string a_name) { _name = a_name; }
const PatchNameList& patch_name_list() const { return _patch_name_list; }
const PatchPrimaryKey* patch_primary_key() const { return _id; }
XMLNode& get_state (void);
int set_state (const XMLNode& a_node);
private:
string _name;
PatchNameList _patch_name_list;
string _name;
PatchNameList _patch_name_list;
PatchPrimaryKey* _id;
};
#include <iostream>

View File

@ -38,27 +38,22 @@ Patch::get_state (void)
XMLNode* node = new XMLNode("Patch");
node->add_property("Number", _number);
node->add_property("Name", _name);
/*
XMLNode* commands = node->add_child("PatchMIDICommands");
for (PatchMidiCommands::const_iterator event = _patch_midi_commands.begin();
event != _patch_midi_commands.end();
++event) {
commands->add_child_copy(*((((Evoral::MIDIEvent&)*event)).to_xml()));
}
*/
return *node;
}
int
Patch::set_state (const XMLNode& node)
void initialize_primary_key_from_commands (PatchPrimaryKey& id, const XMLNode* node)
{
assert(node.name() == "Patch");
_number = node.property("Number")->value();
_name = node.property("Name")->value();
XMLNode* commands = node.child("PatchMIDICommands");
assert(commands);
const XMLNodeList events = commands->children();
const XMLNodeList events = node->children();
for (XMLNodeList::const_iterator i = events.begin(); i != events.end(); ++i) {
_patch_midi_commands.push_back(boost::shared_ptr<Evoral::MIDIEvent> (new Evoral::MIDIEvent(*(*i))));
XMLNode* node = *i;
if (node->name() == "ControlChange") {
string control = node->property("Control")->value();
@ -67,18 +62,42 @@ Patch::set_state (const XMLNode& node)
assert(value != "");
if (control == "0") {
_id.msb = PBD::atoi(value);
id.msb = PBD::atoi(value);
} else if (control == "32") {
_id.lsb = PBD::atoi(value);
id.lsb = PBD::atoi(value);
}
} else if (node->name() == "ProgramChange") {
string number = node->property("Number")->value();
assert(number != "");
_id.program_number = PBD::atoi(number);
id.program_number = PBD::atoi(number);
}
}
}
int
Patch::set_state (const XMLNode& node)
{
assert(node.name() == "Patch");
_number = node.property("Number")->value();
_name = node.property("Name")->value();
XMLNode* commands = node.child("PatchMIDICommands");
if (commands) {
initialize_primary_key_from_commands(_id, commands);
} else {
string program_change = node.property("ProgramChange")->value();
assert(program_change.length());
assert(_bank);
assert(_bank->patch_primary_key());
if ( _bank && _bank->patch_primary_key() ) {
_id.msb = _bank->patch_primary_key()->msb;
_id.lsb = _bank->patch_primary_key()->lsb;
_id.program_number = PBD::atoi(program_change);
}
}
//cerr << "deserialized Patch: name: " << _name << _id.msb << " lsb: " << _id.lsb << " program " << _id.program_number << endl;
cerr << "deserialized Patch: name: " << _name << " msb: " << _id.msb << " lsb: " << _id.lsb << " program " << _id.program_number << endl;
// TODO: handle that more gracefully
assert(_id.is_sane());
@ -152,15 +171,22 @@ PatchBank::set_state (const XMLNode& node)
{
assert(node.name() == "PatchBank");
_name = node.property("Name")->value();
XMLNode* commands = node.child("MIDICommands");
if (commands) {
_id = new PatchPrimaryKey();
initialize_primary_key_from_commands(*_id, commands);
}
XMLNode* patch_name_list = node.child("PatchNameList");
assert(patch_name_list);
const XMLNodeList patches = patch_name_list->children();
for (XMLNodeList::const_iterator i = patches.begin(); i != patches.end(); ++i) {
boost::shared_ptr<Patch> patch(new Patch());
boost::shared_ptr<Patch> patch(new Patch(this));
patch->set_state(*(*i));
_patch_name_list.push_back(patch);
}
return 0;
}