lots and lots of work to correctly deduce AU IO configurations and related issues
[ardour.git] / libs / ardour / globals.cc
index 10d67421fb018d65332903c65dc88923eb908854..c5f96d67647da6f2c9f98ad4fb545e72b64a1b25 100644 (file)
 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <locale.h>
+#include <errno.h>
 
 #ifdef VST_SUPPORT
 #include <fst.h>
 #endif
 
+#ifdef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
+
 #ifdef __SSE__
 #include <xmmintrin.h>
 #endif
 
 #include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
 
 #include <lrdf.h>
 
 #include <pbd/id.h>
 #include <pbd/strsplit.h>
 #include <pbd/fpu.h>
+#include <pbd/pathscanner.h>
 
 #include <midi++/port.h>
 #include <midi++/manager.h>
 #include <midi++/mmc.h>
 
 #include <ardour/ardour.h>
+#include <ardour/analyser.h>
 #include <ardour/audio_library.h>
 #include <ardour/configuration.h>
 #include <ardour/profile.h>
@@ -90,6 +100,8 @@ Change ARDOUR::PositionChanged = ARDOUR::new_change ();
 Change ARDOUR::NameChanged = ARDOUR::new_change ();
 Change ARDOUR::BoundsChanged = Change (0); // see init(), below
 
+sigc::signal<void,std::string> ARDOUR::BootMessage;
+
 #ifdef HAVE_LIBLO
 static int
 setup_osc ()
@@ -101,6 +113,7 @@ setup_osc ()
        osc = new OSC (Config->get_osc_port());
        
        if (Config->get_use_osc ()) {
+               BootMessage (_("Starting OSC"));
                return osc->start ();
        } else {
                return 0;
@@ -116,6 +129,8 @@ setup_midi ()
                return 0;
        }
 
+       BootMessage (_("Configuring MIDI ports"));
+
        for (std::map<string,XMLNode>::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
                MIDI::Manager::instance()->add_port (i->second);
        }
@@ -248,6 +263,33 @@ setup_hardware_optimization (bool try_optimization)
 
 }
 
+static void
+lotsa_files_please ()
+{
+       struct rlimit rl;
+
+       if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
+
+               rl.rlim_cur = rl.rlim_max;
+
+               if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
+                       if (rl.rlim_cur == RLIM_INFINITY) {
+                               error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
+                       } else {
+                               error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
+                       }
+               } else {
+                       if (rl.rlim_cur == RLIM_INFINITY) {
+                               info << _("Removed open file count limit. Excellent!") << endmsg;
+                       } else {
+                               info << string_compose (_("Ardour will be limited to %1 open files"), rl.rlim_cur) << endmsg;
+                       }
+               }
+       } else {
+               error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
+       }
+}
+
 int
 ARDOUR::init (bool use_vst, bool try_optimization)
 {
@@ -257,9 +299,14 @@ ARDOUR::init (bool use_vst, bool try_optimization)
 
        setup_enum_writer ();
 
+       // allow ardour the absolute maximum number of open files
+       lotsa_files_please ();
+
        lrdf_init();
        Library = new AudioLibrary;
 
+       BootMessage (_("Loading configuration"));
+
        Config = new Configuration;
 
        if (Config->load_state ()) {
@@ -286,9 +333,25 @@ ARDOUR::init (bool use_vst, bool try_optimization)
        }
 #endif
 
+#ifdef HAVE_AUDIOUNITS
+       AUPluginInfo::load_cached_info ();
+#endif
+       
+       /* Make VAMP look in our library ahead of anything else */
+
+       char *p = getenv ("VAMP_PATH");
+       string vamppath = VAMP_DIR;
+       if (p) {
+               vamppath += ':';
+               vamppath += p;
+       } 
+       setenv ("VAMP_PATH", vamppath.c_str(), 1);
+
+
        setup_hardware_optimization (try_optimization);
 
        SourceFactory::init ();
+       Analyser::init ();
 
        /* singleton - first object is "it" */
        new PluginManager ();
@@ -358,13 +421,13 @@ string
 ARDOUR::get_user_ardour_path ()
 {
        string path;
-       char* envvar;
-       
-       if ((envvar = getenv ("HOME")) == 0 || strlen (envvar) == 0) {
+               
+       path = Glib::get_home_dir();
+
+       if (path.empty()) {
                return "/";
        }
-               
-       path = envvar;
+
        path += "/.ardour2/";
 
        /* create it if necessary */
@@ -438,36 +501,91 @@ find_file (string name, string dir, string subdir = "")
        path = get_user_ardour_path();
                
        if (subdir.length()) {
-               path += subdir + "/";
+               path = Glib::build_filename (path, subdir);
        }
                
-       path += name;
-       if (access (path.c_str(), R_OK) == 0) {
+       path = Glib::build_filename (path, name);
+
+       if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS)) {
                return path;
        }
 
-       /* 3rd attempt: dir/... */
-       
-       path = dir;
-       path += "/ardour2/";
-       
-       if (subdir.length()) {
-               path += subdir + "/";
+       if (dir.length()) {
+               /* 3rd attempt: dir/... */
+               
+               path = dir;
+               path += "/ardour2/";
+               
+               if (subdir.length()) {
+                       path += subdir + "/";
+               }
+               
+               path += name;
+               
+               if (access (path.c_str(), R_OK) == 0) {
+                       return path;
+               }
        }
+
+       return "";
+}
+
+static bool sae_binding_filter (const string& str, void* arg)
+{
+       /* Not a dotfile, has a prefix before a period, suffix is ".bindings" and contains -sae- */
+       
+       return str[0] != '.' && str.length() > 13 && str.find (".bindings") == (str.length() - 9)
+               && str.find ("SAE-") != string::npos;
+}
+
+static bool binding_filter (const string& str, void* arg)
+{
+       /* Not a dotfile, has a prefix before a period, suffix is ".bindings" */
        
-       path += name;
+       return str[0] != '.' && str.length() > 9 && str.find (".bindings") == (str.length() - 9);
+}
+
+void
+ARDOUR::find_bindings_files (map<string,string>& files)
+{
+       PathScanner scanner;
+       vector<string*> *found;
+       string full_path;
        
-       if (access (path.c_str(), R_OK) == 0) {
-               return path;
+       /* XXX building path, so separators are fixed */
+
+       full_path = get_user_ardour_path ();
+       full_path += ':';
+       full_path = get_system_data_path ();
+
+       if (getenv ("ARDOUR_SAE")) {
+               found = scanner (full_path, sae_binding_filter, 0, false, true);
+       } else {
+               found = scanner (full_path, binding_filter, 0, false, true);
        }
 
-       return "";
+       if (!found) {
+               return;
+       }
+       
+       for (vector<string*>::iterator x = found->begin(); x != found->end(); ++x) {
+               string path = *(*x);
+               pair<string,string> namepath;
+               namepath.second = path;
+               path = Glib::path_get_basename (path);
+               namepath.first = path.substr (0, path.find_first_of ('.'));
+               
+               files.insert (namepath);
+               delete *x;
+       }
+       
+       delete found;
 }
 
 string
 ARDOUR::find_config_file (string name)
 {
-       char* envvar;
+       const char* envvar;
 
        if ((envvar = getenv("ARDOUR_CONFIG_PATH")) == 0) {
                envvar = CONFIG_DIR;
@@ -479,7 +597,7 @@ ARDOUR::find_config_file (string name)
 string
 ARDOUR::find_data_file (string name, string subdir)
 {
-       char* envvar;
+       const char* envvar;
        if ((envvar = getenv("ARDOUR_DATA_PATH")) == 0) {
                envvar = DATA_DIR;
        }