#include <time.h>
#include <glib.h>
-#include <pbd/gstdio_compat.h>
+#include "pbd/gstdio_compat.h"
#ifdef PLATFORM_WINDOWS
+#include <stdio.h> // for _setmaxstdio
#include <windows.h> // for LARGE_INTEGER
#endif
#include "pbd/fpu.h"
#include "pbd/file_utils.h"
#include "pbd/enumwriter.h"
-#include "pbd/basename.h"
#include "midi++/port.h"
#include "midi++/mmc.h"
+#include "LuaBridge/LuaBridge.h"
+
#include "ardour/analyser.h"
#include "ardour/audio_library.h"
#include "ardour/audio_backend.h"
#include "ardour/event_type_map.h"
#include "ardour/filesystem_paths.h"
#include "ardour/midi_region.h"
+#include "ardour/midi_ui.h"
#include "ardour/midiport_manager.h"
#include "ardour/mix.h"
#include "ardour/operations.h"
#include "ardour/panner_manager.h"
#include "ardour/plugin_manager.h"
+#include "ardour/presentation_info.h"
#include "ardour/process_thread.h"
#include "ardour/profile.h"
#include "ardour/rc_configuration.h"
#include "ardour/runtime_functions.h"
#include "ardour/session_event.h"
#include "ardour/source_factory.h"
+#include "ardour/transport_master_manager.h"
+#ifdef LV2_SUPPORT
#include "ardour/uri_map.h"
-
+#endif
#include "audiographer/routines.h"
#if defined (__APPLE__)
- #include <Carbon/Carbon.h> // For Gestalt
+#include <CoreFoundation/CoreFoundation.h>
#endif
-#include "i18n.h"
+#include "pbd/i18n.h"
ARDOUR::RCConfiguration* ARDOUR::Config = 0;
ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
-copy_vector_t ARDOUR::copy_vector = 0;
+copy_vector_t ARDOUR::copy_vector = 0;
PBD::Signal1<void,std::string> ARDOUR::BootMessage;
PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
PBD::Signal0<void> ARDOUR::GUIIdle;
PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
-std::vector<std::string> ARDOUR::reserved_io_names;
+std::map<std::string, bool> ARDOUR::reserved_io_names;
static bool have_old_configuration_files = false;
*/
PBD::PropertyChange ARDOUR::bounds_change;
+static PBD::ScopedConnection engine_startup_connection;
+
void
setup_hardware_optimization (bool try_optimization)
{
#ifdef PLATFORM_WINDOWS
/* We have AVX-optimized code for Windows */
-
+
if (fpu->has_avx()) {
-#else
+#else
/* AVX code doesn't compile on Linux yet */
-
+
if (false) {
-#endif
+#endif
info << "Using AVX optimized routines" << endmsg;
-
+
// AVX SET
compute_peak = x86_sse_avx_compute_peak;
find_peaks = x86_sse_avx_find_peaks;
}
#elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
- SInt32 sysVersion = 0;
-
- if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
- sysVersion = 0;
- if (sysVersion >= 0x00001040) { // Tiger at least
+ if (floor (kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_4) { /* at least Tiger */
compute_peak = veclib_compute_peak;
find_peaks = veclib_find_peaks;
apply_gain_to_buffer = veclib_apply_gain_to_buffer;
}
} else {
if (rl.rlim_cur != RLIM_INFINITY) {
- info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
+ info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
}
}
} else {
error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
}
+#else
+ /* this only affects stdio. 2048 is the maxium possible (512 the default).
+ *
+ * If we want more, we'll have to replaces the POSIX I/O interfaces with
+ * Win32 API calls (CreateFile, WriteFile, etc) which allows for 16K.
+ *
+ * see http://stackoverflow.com/questions/870173/is-there-a-limit-on-number-of-open-files-in-windows
+ * and http://bugs.mysql.com/bug.php?id=24509
+ */
+ int newmax = _setmaxstdio (2048);
+ if (newmax > 0) {
+ info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, newmax) << endmsg;
+ } else {
+ error << string_compose (_("Could not set system open files limit. Current limit is %1 open files"), _getmaxstdio()) << endmsg;
+ }
#endif
}
if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
return -1;
}
-
- if (old_version == 3) {
-
+
+ if (old_version >= 3) {
+
old_name = Glib::build_filename (old_dir, X_("recent"));
new_name = Glib::build_filename (new_dir, X_("recent"));
* $CONFIG/ardour.rc. Pick up the newer "old" config file,
* to avoid confusion.
*/
-
+
string old_name = Glib::build_filename (old_dir, X_("config"));
if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
old_name = Glib::build_filename (old_dir, X_("presets"));
new_name = Glib::build_filename (new_dir, X_("presets"));
-
+
copy_recurse (old_name, new_name);
- /* presets */
+ /* plugin status */
+ g_mkdir_with_parents (Glib::build_filename (new_dir, plugin_metadata_dir_name).c_str(), 0755);
- old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
- new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
+ old_name = Glib::build_filename (old_dir, X_("plugin_statuses")); /* until 6.0 */
+ new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
+ copy_file (old_name, new_name); /* can fail silently */
+ old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
copy_file (old_name, new_name);
-
+
+ /* plugin tags */
+
+ old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_tags"));
+ new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_tags"));
+
+ copy_file (old_name, new_name);
+
/* export formats */
old_name = Glib::build_filename (old_dir, export_formats_dir_name);
new_name = Glib::build_filename (new_dir, export_formats_dir_name);
-
+
vector<string> export_formats;
g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
find_files_matching_pattern (export_formats, old_name, X_("*.format"));
ARDOUR::check_for_old_configuration_files ()
{
int current_version = atoi (X_(PROGRAM_VERSION));
-
+
if (current_version <= 1) {
return;
}
return true;
}
+#ifndef NDEBUG
+ if (getenv("LUA_METATABLES")) {
+ luabridge::Security::setHideMetatables (false);
+ }
+#endif
+
if (!PBD::init()) return false;
-#ifdef ENABLE_NLS
+#if ENABLE_NLS
(void) bindtextdomain(PACKAGE, localedir);
(void) bind_textdomain_codeset (PACKAGE, "UTF-8");
#endif
RouteGroup::make_property_quarks ();
Playlist::make_property_quarks ();
AudioPlaylist::make_property_quarks ();
+ PresentationInfo::make_property_quarks ();
+ TransportMaster::make_property_quarks ();
/* this is a useful ready to use PropertyChange that many
things need to check. This avoids having to compose
#endif
(void) EventTypeMap::instance();
+ ControlProtocolManager::instance().discover_control_protocols ();
+
+ /* for each control protocol, check for a request buffer factory method
+ and if it exists, store it in the EventLoop list of such
+ methods. This allows the relevant threads to register themselves
+ with EventLoops so that signal emission can be RT-safe.
+ */
+
+ ControlProtocolManager::instance().register_request_buffer_factories ();
+ /* it would be nice if this could auto-register itself in the
+ constructor, since MidiControlUI is a singleton, but it can't be
+ created until after the engine is running. Therefore we have to
+ explicitly register it here.
+ */
+ EventLoop::register_request_buffer_factory (X_("midiUI"), MidiControlUI::request_factory);
+
ProcessThread::init ();
/* the + 4 is a bit of a handwave. i don't actually know
how many more per-thread buffer sets we need above
support may not even be active. Without adding an API to control
surface support that would list their port names, we do have to
list them here.
+
+ We also need to know if the given I/O is an actual route.
+ For routes (e.g. "master"), bus creation needs to be allowed the first time,
+ while for pure I/O (e.g. "Click") track/bus creation must always fail.
*/
-
- char const * const reserved[] = {
- _("Monitor"),
- _("Master"),
- _("Control"),
- _("Click"),
- _("Mackie"),
- 0
- };
-
- for (int n = 0; reserved[n]; ++n) {
- reserved_io_names.push_back (reserved[n]);
- }
-
+
+ reserved_io_names[_("Monitor")] = true;
+ reserved_io_names[_("Master")] = true;
+ reserved_io_names["auditioner"] = true; // auditioner.cc Track (s, "auditioner",...)
+
+ /* pure I/O */
+ reserved_io_names[X_("Click")] = false; // session.cc ClickIO (*this, X_("Click")
+ reserved_io_names[_("Control")] = false;
+ reserved_io_names[_("Mackie")] = false;
+ reserved_io_names[_("FaderPort Recv")] = false;
+ reserved_io_names[_("FaderPort Send")] = false;
+ reserved_io_names[_("FaderPort2 Recv")] = false;
+ reserved_io_names[_("FaderPort2 Send")] = false;
+ reserved_io_names[_("FaderPort8 Recv")] = false;
+ reserved_io_names[_("FaderPort8 Send")] = false;
+ reserved_io_names[_("FaderPort16 Recv")] = false;
+ reserved_io_names[_("FaderPort16 Send")] = false;
+
libardour_initialized = true;
return true;
}
void
-ARDOUR::init_post_engine ()
+ARDOUR::init_post_engine (uint32_t start_cnt)
{
- ControlProtocolManager::instance().discover_control_protocols ();
-
XMLNode* node;
- if ((node = Config->control_protocol_state()) != 0) {
- ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
+
+ if (start_cnt == 0) {
+
+ /* find plugins */
+
+ ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
}
- /* find plugins */
+ if (start_cnt == 0) {
+
+ if ((node = Config->control_protocol_state()) != 0) {
+ ControlProtocolManager::instance().set_state (*node, 0 /* here: global-config state */);
+ }
- ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
+ TransportMasterManager::instance().restart ();
+ }
}
void
return;
}
+ engine_startup_connection.disconnect ();
+
+ delete &ControlProtocolManager::instance();
ARDOUR::AudioEngine::destroy ();
delete Library;
#ifdef HAVE_LRDF
lrdf_cleanup ();
#endif
- delete &ControlProtocolManager::instance();
#ifdef WINDOWS_VST_SUPPORT
fst_exit ();
#endif
return;
}
-void
-ARDOUR::find_bindings_files (map<string,string>& files)
-{
- vector<std::string> found;
- Searchpath spath = ardour_config_search_path();
-
- if (getenv ("ARDOUR_SAE")) {
- find_files_matching_pattern (found, spath, "*SAE-*.bindings");
- } else {
- find_files_matching_pattern (found, spath, "*.bindings");
- }
-
- if (found.empty()) {
- return;
- }
-
- for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
- std::string path(*x);
- pair<string,string> namepath;
- namepath.second = path;
- namepath.first = PBD::basename_nosuffix (path);
- files.insert (namepath);
- }
-}
-
bool
ARDOUR::no_auto_connect()
{
ARDOUR::setup_fpu ()
{
FPU* fpu = FPU::instance ();
-
+
if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
// valgrind doesn't understand this assembler stuff
// September 10th, 2007
#ifdef DEBUG_DENORMAL_EXCEPTION
/* This will raise a FP exception if a denormal is detected */
MXCSR &= ~_MM_MASK_DENORM;
-#endif
+#endif
switch (Config->get_denormal_model()) {
case DenormalNone:
if (fd < 0) {
return false;
}
-
+
char c;
-
+
if (yn) {
c = '1';
} else {
c = '0';
}
-
+
(void) ::write (fd, &c, 1);
(void) ::close (fd);
+ Config->ParameterChanged ("enable-translation");
return true;
}