MCP: loading device info files basically operational

git-svn-id: svn://localhost/ardour2/branches/3.0@11939 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2012-04-12 12:58:42 +00:00
parent 3a4a45caae
commit abf8069d7f
6 changed files with 160 additions and 61 deletions

View File

@@ -17,7 +17,14 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cstring>
#include <glibmm/miscutils.h>
#include "pbd/xml++.h"
#include "pbd/error.h"
#include "pbd/pathscanner.h"
#include "ardour/filesystem_paths.h"
#include "device_info.h"
@@ -25,7 +32,11 @@
using namespace Mackie;
using namespace PBD;
using namespace ARDOUR;
using std::string;
using std::vector;
std::map<std::string,DeviceInfo> DeviceInfo::device_info;
DeviceInfo::DeviceInfo()
: _strip_cnt (8)
@@ -46,36 +57,55 @@ int
DeviceInfo::set_state (const XMLNode& node, int /* version */)
{
const XMLProperty* prop;
if ((prop = node.property ("strips")) != 0) {
if ((_strip_cnt = atoi (prop->value())) == 0) {
_strip_cnt = 8;
const XMLNode* child;
if ((child = node.child ("Strips")) != 0) {
if ((prop = node.property ("value")) != 0) {
if ((_strip_cnt = atoi (prop->value())) == 0) {
_strip_cnt = 8;
}
}
}
if ((prop = node.property ("two-character-display")) != 0) {
_has_two_character_display = string_is_affirmative (prop->value());
if ((child = node.child ("TwoCharacterDisplay")) != 0) {
if ((prop = node.property ("value")) != 0) {
_has_two_character_display = string_is_affirmative (prop->value());
}
}
if ((prop = node.property ("master-fader")) != 0) {
_has_master_fader = string_is_affirmative (prop->value());
if ((child = node.child ("MasterFader")) != 0) {
if ((prop = node.property ("value")) != 0) {
_has_master_fader = string_is_affirmative (prop->value());
}
}
if ((prop = node.property ("display-segmented")) != 0) {
_has_segmented_display = string_is_affirmative (prop->value());
if ((child = node.child ("DisplaySegments")) != 0) {
if ((prop = node.property ("value")) != 0) {
_has_segmented_display = string_is_affirmative (prop->value());
}
}
if ((prop = node.property ("timecode-display")) != 0) {
_has_timecode_display = string_is_affirmative (prop->value());
if ((child = node.child ("TimecodeDisplay")) != 0) {
if ((prop = node.property ("value")) != 0) {
_has_timecode_display = string_is_affirmative (prop->value());
}
}
if ((prop = node.property ("name")) != 0) {
_name = prop->value();
if ((child = node.child ("Name")) != 0) {
if ((prop = node.property ("value")) != 0) {
_name = prop->value();
}
}
return 0;
}
const string&
DeviceInfo::name() const
{
return _name;
}
uint32_t
DeviceInfo::strip_cnt() const
{
@@ -106,3 +136,91 @@ DeviceInfo::has_timecode_display () const
return _has_timecode_display;
}
static const char * const devinfo_env_variable_name = "ARDOUR_MCP_DEVINFO_PATH";
static const char* const devinfo_dir_name = "mcp_devices";
static const char* const devinfo_suffix = ".xml";
static sys::path
system_devinfo_search_path ()
{
bool devinfo_path_defined = false;
sys::path spath_env (Glib::getenv (devinfo_env_variable_name, devinfo_path_defined));
if (devinfo_path_defined) {
return spath_env;
}
SearchPath spath (system_data_search_path());
spath.add_subdirectory_to_paths(devinfo_dir_name);
// just return the first directory in the search path that exists
SearchPath::const_iterator i = std::find_if(spath.begin(), spath.end(), sys::exists);
if (i == spath.end()) return sys::path();
return *i;
}
static sys::path
user_devinfo_directory ()
{
sys::path p(user_config_directory());
p /= devinfo_dir_name;
return p;
}
static bool
devinfo_filter (const string &str, void */*arg*/)
{
return (str.length() > strlen(devinfo_suffix) &&
str.find (devinfo_suffix) == (str.length() - strlen (devinfo_suffix)));
}
void
DeviceInfo::reload_device_info ()
{
DeviceInfo di;
vector<string> s;
vector<string *> *devinfos;
PathScanner scanner;
SearchPath spath (system_devinfo_search_path());
spath += user_devinfo_directory ();
devinfos = scanner (spath.to_string(), devinfo_filter, 0, false, true);
device_info.clear ();
if (!devinfos) {
error << "No MCP device info files found using " << spath.to_string() << endmsg;
std::cerr << "No MCP device info files found using " << spath.to_string() << std::endl;
return;
}
if (devinfos->empty()) {
error << "No MCP device info files found using " << spath.to_string() << endmsg;
std::cerr << "No MCP device info files found using " << spath.to_string() << std::endl;
return;
}
for (vector<string*>::iterator i = devinfos->begin(); i != devinfos->end(); ++i) {
string fullpath = *(*i);
XMLTree tree;
if (!tree.read (fullpath.c_str())) {
continue;
}
XMLNode* root = tree.root ();
if (!root) {
continue;
}
di.set_state (*root, 3000); /* version is ignored for now */
device_info[di.name()] = di;
}
delete devinfos;
}

View File

@@ -22,6 +22,7 @@
#include <stdint.h>
#include <string>
#include <map>
class XMLNode;
@@ -42,6 +43,9 @@ class DeviceInfo
bool has_timecode_display() const;
const std::string& name() const;
static std::map<std::string,DeviceInfo> device_info;
static void reload_device_info();
private:
uint32_t _strip_cnt;
bool _has_two_character_display;

View File

@@ -22,10 +22,14 @@
#include <gtkmm/table.h>
#include "gtkmm2ext/utils.h"
#include "ardour/rc_configuration.h"
#include "mackie_control_protocol.h"
#include "device_info.h"
#include "i18n.h"
using namespace std;
using namespace Mackie;
class MackieControlProtocolGUI : public Gtk::VBox
{
@@ -73,9 +77,13 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
table->attach (*manage (new Gtk::Label (_("Surface type:"))), 0, 1, 0, 1);
table->attach (_surface_combo, 1, 2, 0, 1);
vector<string> surfaces = p.get_possible_devices ();
vector<string> surfaces;
for (std::map<std::string,DeviceInfo>::iterator i = DeviceInfo::device_info.begin(); i != DeviceInfo::device_info.end(); ++i) {
surfaces.push_back (i->first);
}
Gtkmm2ext::set_popdown_strings (_surface_combo, surfaces);
_surface_combo.set_active_text (p.device_name());
_surface_combo.set_active_text (p.device_info().name());
_extenders.set_range (0, 8);
_extenders.set_increments (1, 4);

View File

@@ -15,14 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "control_protocol/control_protocol.h"
#include "mackie_control_protocol.h"
#include "ardour/rc_configuration.h"
#include <stdexcept>
#include "pbd/error.h"
#include <stdexcept>
#include "ardour/rc_configuration.h"
#include "control_protocol/control_protocol.h"
#include "mackie_control_protocol.h"
using namespace ARDOUR;
using namespace PBD;

View File

@@ -92,7 +92,6 @@ bool MackieControlProtocol::probe()
MackieControlProtocol::MackieControlProtocol (Session& session)
: ControlProtocol (session, X_("Mackie"), this)
, AbstractUI<MackieControlUIRequest> ("mackie")
, _device_name (get_possible_devices().front())
, _current_initial_bank (0)
, _timecode_type (ARDOUR::AnyTime::BBT)
, _input_bundle (new ARDOUR::Bundle (_("Mackie Control In"), true))
@@ -106,6 +105,8 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
{
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
DeviceInfo::reload_device_info ();
AudioEngine::instance()->PortConnectedOrDisconnected.connect (
audio_engine_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
this
@@ -563,7 +564,7 @@ MackieControlProtocol::get_state()
XMLNode* node = new XMLNode (X_("Protocol"));
node->add_property (X_("name"), ARDOUR::ControlProtocol::_name);
node->add_property (X_("device"), _device_name);
node->add_property (X_("device"), _device_info.name());
// add current bank
ostringstream os;
@@ -1145,45 +1146,15 @@ MackieControlProtocol::force_special_route_to_strip (boost::shared_ptr<Route> r,
}
}
vector<string>
MackieControlProtocol::get_possible_devices ()
{
vector<string> s;
s.push_back (X_("Mackie Control Universal Pro"));
s.push_back (X_("Behringer BCF2000"));
s.push_back (X_("SSL Nucleus"));
s.push_back (X_("Presonus FaderPort"));
return s;
}
string
MackieControlProtocol::find_device_info_file (const string& name)
{
return string();
}
void
MackieControlProtocol::load_device_info (const string& name)
{
string path = find_device_info_file (name);
map<string,DeviceInfo>::iterator i = DeviceInfo::device_info.find (name);
if (path.empty()) {
if (i == DeviceInfo::device_info.end()) {
error << string_compose (_("No device info for Mackie Control device \"%1\" - ignored"), name) << endmsg;
return;
}
XMLTree tree;
if (tree.read (path)) {
error << string_compose (_("Cannot load device info file %1 - ignored"), path) << endmsg;
return;
}
XMLNode* root = tree.root();
if (root) {
if (_device_info.set_state (*root, 3000)) { // version is currently ignored
_device_name = name;
}
}
_device_info = i->second;
}

View File

@@ -112,9 +112,8 @@ class MackieControlProtocol
virtual ~MackieControlProtocol();
static MackieControlProtocol* instance() { return _instance; }
const std::string& device_name() const { return _device_name; }
static std::vector<std::string> get_possible_devices ();
const Mackie::DeviceInfo& device_info() const { return _device_info; }
int set_active (bool yn);
@@ -238,7 +237,6 @@ class MackieControlProtocol
static MackieControlProtocol* _instance;
std::string _device_name;
Mackie::DeviceInfo _device_info;
sigc::connection periodic_connection;
uint32_t _current_initial_bank;
@@ -268,7 +266,6 @@ class MackieControlProtocol
std::vector<std::string> _f_actions;
ButtonMap button_map;
std::string find_device_info_file (const std::string& name);
void load_device_info (const std::string&);
void create_surfaces ();
void port_connected_or_disconnected (std::string, std::string, bool);