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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user