monitor send gets access to the (shared) pannable of the track/bus, thus ensuring...
[ardour.git] / libs / ardour / globals.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifdef WAF_BUILD
20 #include "libardour-config.h"
21 #endif
22
23 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <sys/resource.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <errno.h>
31
32 #ifdef VST_SUPPORT
33 #include <fst.h>
34 #endif
35
36 #ifdef HAVE_AUDIOUNITS
37 #include "ardour/audio_unit.h"
38 #endif
39
40 #ifdef __SSE__
41 #include <xmmintrin.h>
42 #endif
43
44 #include <glibmm/fileutils.h>
45 #include <glibmm/miscutils.h>
46
47 #include <lrdf.h>
48
49 #include "pbd/error.h"
50 #include "pbd/id.h"
51 #include "pbd/strsplit.h"
52 #include "pbd/fpu.h"
53 #include "pbd/file_utils.h"
54 #include "pbd/enumwriter.h"
55
56 #include "midi++/port.h"
57 #include "midi++/manager.h"
58 #include "midi++/mmc.h"
59
60 #include "ardour/analyser.h"
61 #include "ardour/ardour.h"
62 #include "ardour/audio_library.h"
63 #include "ardour/audioengine.h"
64 #include "ardour/audioregion.h"
65 #include "ardour/audiosource.h"
66 #include "ardour/buffer_manager.h"
67 #include "ardour/control_protocol_manager.h"
68 #include "ardour/debug.h"
69 #include "ardour/filesystem_paths.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/mix.h"
72 #include "ardour/audioplaylist.h"
73 #include "ardour/panner_manager.h"
74 #include "ardour/plugin_manager.h"
75 #include "ardour/process_thread.h"
76 #include "ardour/profile.h"
77 #include "ardour/region.h"
78 #include "ardour/rc_configuration.h"
79 #include "ardour/route_group.h"
80 #include "ardour/runtime_functions.h"
81 #include "ardour/session.h"
82 #include "ardour/session_event.h"
83 #include "ardour/source_factory.h"
84 #include "ardour/utils.h"
85
86 #include "audiographer/routines.h"
87
88 #if defined (__APPLE__)
89        #include <Carbon/Carbon.h> // For Gestalt
90 #endif
91
92 #include "i18n.h"
93
94 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
95 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
96 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
97
98 using namespace ARDOUR;
99 using namespace std;
100 using namespace PBD;
101
102 compute_peak_t          ARDOUR::compute_peak = 0;
103 find_peaks_t            ARDOUR::find_peaks = 0;
104 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
105 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
106 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
107
108 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
109
110 void ARDOUR::setup_enum_writer ();
111
112 /* this is useful for quite a few things that want to check
113    if any bounds-related property has changed
114 */
115 PBD::PropertyChange ARDOUR::bounds_change;
116
117 namespace ARDOUR {
118         namespace Properties {
119
120                 /* the envelope and fades are not scalar items and so
121                    currently (2010/02) are not stored using Property.
122                    However, these descriptors enable us to notify
123                    about changes to them via PropertyChange.
124
125                    Declared in ardour/audioregion.h ...
126                 */
127
128                 PBD::PropertyDescriptor<bool> fade_in;
129                 PBD::PropertyDescriptor<bool> fade_out;
130                 PBD::PropertyDescriptor<bool> envelope;
131         }
132 }
133
134 void
135 ARDOUR::make_property_quarks ()
136 {
137         Properties::fade_in.property_id = g_quark_from_static_string (X_("fade_in_FAKE"));
138         DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_in_FAKE = %1\n",        Properties::fade_in.property_id));
139         Properties::fade_out.property_id = g_quark_from_static_string (X_("fade_out_FAKE"));
140         DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_out_FAKE = %1\n",       Properties::fade_out.property_id));
141         Properties::envelope.property_id = g_quark_from_static_string (X_("envelope_FAKE"));
142         DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope_FAKE = %1\n",       Properties::envelope.property_id));
143 }
144
145 void
146 setup_hardware_optimization (bool try_optimization)
147 {
148         bool generic_mix_functions = true;
149
150         if (try_optimization) {
151
152                 FPU fpu;
153
154 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
155
156                 if (fpu.has_sse()) {
157
158                         info << "Using SSE optimized routines" << endmsg;
159
160                         // SSE SET
161                         compute_peak          = x86_sse_compute_peak;
162                         find_peaks            = x86_sse_find_peaks;
163                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
164                         // mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
165                         mix_buffers_with_gain = default_mix_buffers_with_gain;
166                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
167
168                         generic_mix_functions = false;
169
170                 }
171
172 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
173                 long sysVersion = 0;
174
175                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
176                         sysVersion = 0;
177
178                 if (sysVersion >= 0x00001040) { // Tiger at least
179                         compute_peak           = veclib_compute_peak;
180                         find_peaks             = veclib_find_peaks;
181                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
182                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
183                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
184
185                         generic_mix_functions = false;
186
187                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
188                 }
189 #endif
190
191                 /* consider FPU denormal handling to be "h/w optimization" */
192
193                 setup_fpu ();
194         }
195
196         if (generic_mix_functions) {
197
198                 compute_peak          = default_compute_peak;
199                 find_peaks            = default_find_peaks;
200                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
201                 mix_buffers_with_gain = default_mix_buffers_with_gain;
202                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
203
204                 info << "No H/W specific optimizations in use" << endmsg;
205         }
206
207         AudioGrapher::Routines::override_compute_peak (compute_peak);
208         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
209 }
210
211 static void
212 lotsa_files_please ()
213 {
214         struct rlimit rl;
215
216         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
217
218                 rl.rlim_cur = rl.rlim_max;
219
220                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
221                         if (rl.rlim_cur == RLIM_INFINITY) {
222                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
223                         } else {
224                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
225                         }
226                 } else {
227                         if (rl.rlim_cur == RLIM_INFINITY) {
228                                 info << _("Removed open file count limit. Excellent!") << endmsg;
229                         } else {
230                                 info << string_compose (_("%1 will be limited to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
231                         }
232                 }
233         } else {
234                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
235         }
236 }
237
238 int
239 ARDOUR::init (bool use_vst, bool try_optimization)
240 {
241         if (!Glib::thread_supported()) {
242                 Glib::thread_init();
243         }
244
245         (void) bindtextdomain(PACKAGE, LOCALEDIR);
246
247         PBD::ID::init ();
248         SessionEvent::init_event_pool ();
249
250         make_property_quarks ();
251         SessionObject::make_property_quarks ();
252         Region::make_property_quarks ();
253         MidiRegion::make_property_quarks ();
254         AudioRegion::make_property_quarks ();
255         RouteGroup::make_property_quarks ();
256         Playlist::make_property_quarks ();
257         AudioPlaylist::make_property_quarks ();
258
259         /* this is a useful ready to use PropertyChange that many
260            things need to check. This avoids having to compose
261            it every time we want to check for any of the relevant
262            property changes.
263         */
264
265         bounds_change.add (ARDOUR::Properties::start);
266         bounds_change.add (ARDOUR::Properties::position);
267         bounds_change.add (ARDOUR::Properties::length);
268
269         /* provide a state version for the few cases that need it and are not
270            driven by reading state from disk (e.g. undo/redo)
271         */
272
273         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
274
275         setup_enum_writer ();
276
277         // allow ardour the absolute maximum number of open files
278         lotsa_files_please ();
279
280         lrdf_init();
281         Library = new AudioLibrary;
282
283         BootMessage (_("Loading configuration"));
284
285         Config = new RCConfiguration;
286
287         if (Config->load_state ()) {
288                 return -1;
289         }
290
291         Config->set_use_vst (use_vst);
292
293         Profile = new RuntimeProfile;
294
295
296 #ifdef VST_SUPPORT
297         if (Config->get_use_vst() && fst_init (0)) {
298                 return -1;
299         }
300 #endif
301
302 #ifdef HAVE_AUDIOUNITS
303         AUPluginInfo::load_cached_info ();
304 #endif
305
306         /* Make VAMP look in our library ahead of anything else */
307
308         char *p = getenv ("VAMP_PATH");
309         string vamppath = VAMP_DIR;
310         if (p) {
311                 vamppath += ':';
312                 vamppath += p;
313         }
314         setenv ("VAMP_PATH", vamppath.c_str(), 1);
315
316
317         setup_hardware_optimization (try_optimization);
318
319         SourceFactory::init ();
320         Analyser::init ();
321
322         /* singleton - first object is "it" */
323         new PluginManager ();
324
325         ProcessThread::init ();
326         BufferManager::init (10); // XX should be num_processors_for_dsp
327
328         PannerManager::instance().discover_panners();
329
330         return 0;
331 }
332
333 void
334 ARDOUR::init_post_engine ()
335 {
336         /* the MIDI Manager is needed by the ControlProtocolManager */
337         MIDI::Manager::create (AudioEngine::instance()->jack());
338
339         ControlProtocolManager::instance().discover_control_protocols ();
340
341         XMLNode* node;
342         if ((node = Config->control_protocol_state()) != 0) {
343                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
344         }
345 }
346
347 int
348 ARDOUR::cleanup ()
349 {
350         delete Library;
351         lrdf_cleanup ();
352         delete &ControlProtocolManager::instance();
353 #ifdef VST_SUPPORT
354         fst_exit ();
355 #endif
356         return 0;
357 }
358
359 void
360 ARDOUR::find_bindings_files (map<string,string>& files)
361 {
362         vector<sys::path> found;
363         SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
364
365         if (getenv ("ARDOUR_SAE")) {
366                 Glib::PatternSpec pattern("*SAE-*.bindings");
367                 find_matching_files_in_search_path (spath, pattern, found);
368         } else {
369                 Glib::PatternSpec pattern("*.bindings");
370                 find_matching_files_in_search_path (spath, pattern, found);
371         }
372
373         if (found.empty()) {
374                 return;
375         }
376
377         for (vector<sys::path>::iterator x = found.begin(); x != found.end(); ++x) {
378                 sys::path path = *x;
379                 pair<string,string> namepath;
380                 namepath.second = path.to_string();
381                 namepath.first = path.leaf().substr (0, path.leaf().find_first_of ('.'));
382                 files.insert (namepath);
383         }
384 }
385
386 bool
387 ARDOUR::no_auto_connect()
388 {
389         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
390 }
391
392 void
393 ARDOUR::setup_fpu ()
394 {
395
396         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
397                 // valgrind doesn't understand this assembler stuff
398                 // September 10th, 2007
399                 return;
400         }
401
402 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
403
404         int MXCSR;
405         FPU fpu;
406
407         /* XXX use real code to determine if the processor supports
408            DenormalsAreZero and FlushToZero
409         */
410
411         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
412                 return;
413         }
414
415         MXCSR  = _mm_getcsr();
416
417         switch (Config->get_denormal_model()) {
418         case DenormalNone:
419                 MXCSR &= ~(_MM_FLUSH_ZERO_ON|0x8000);
420                 break;
421
422         case DenormalFTZ:
423                 if (fpu.has_flush_to_zero()) {
424                         MXCSR |= _MM_FLUSH_ZERO_ON;
425                 }
426                 break;
427
428         case DenormalDAZ:
429                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
430                 if (fpu.has_denormals_are_zero()) {
431                         MXCSR |= 0x8000;
432                 }
433                 break;
434
435         case DenormalFTZDAZ:
436                 if (fpu.has_flush_to_zero()) {
437                         if (fpu.has_denormals_are_zero()) {
438                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000;
439                         } else {
440                                 MXCSR |= _MM_FLUSH_ZERO_ON;
441                         }
442                 }
443                 break;
444         }
445
446         _mm_setcsr (MXCSR);
447
448 #endif
449 }
450
451 ARDOUR::OverlapType
452 ARDOUR::coverage (framepos_t sa, framepos_t ea,
453                   framepos_t sb, framepos_t eb)
454 {
455         /* OverlapType returned reflects how the second (B)
456            range overlaps the first (A).
457
458            The diagrams show various relative placements
459            of A and B for each OverlapType.
460
461            Notes:
462               Internal: the start points cannot coincide
463               External: the start and end points can coincide
464               Start: end points can coincide
465               End: start points can coincide
466
467            XXX Logically, Internal should disallow end
468            point equality.
469         */
470
471         /*
472              |--------------------|   A
473                   |------|            B
474                 |-----------------|   B
475
476
477              "B is internal to A"
478
479         */
480
481         if ((sb > sa) && (eb <= ea)) {
482                 return OverlapInternal;
483         }
484
485         /*
486              |--------------------|   A
487            ----|                      B
488            -----------------------|   B
489            --|                        B
490
491              "B overlaps the start of A"
492
493         */
494
495         if ((eb >= sa) && (eb <= ea)) {
496                 return OverlapStart;
497         }
498         /*
499              |---------------------|  A
500                    |----------------- B
501              |----------------------- B
502                                    |- B
503
504             "B overlaps the end of A"
505
506         */
507         if ((sb > sa) && (sb <= ea)) {
508                 return OverlapEnd;
509         }
510         /*
511              |--------------------|     A
512            --------------------------  B
513              |-----------------------  B
514             ----------------------|    B
515              |--------------------|    B
516
517
518            "B overlaps all of A"
519         */
520         if ((sa >= sb) && (sa <= eb) && (ea <= eb)) {
521                 return OverlapExternal;
522         }
523
524         return OverlapNone;
525 }
526
527 string
528 ARDOUR::translation_kill_path ()
529 {
530         return Glib::build_filename (user_config_directory().to_string(), ".love_is_the_language_of_audio");
531 }
532
533 bool
534 ARDOUR::translations_are_disabled ()
535 {
536         /* if file does not exist, we don't translate (bundled ardour only) */
537         return Glib::file_test (translation_kill_path(), Glib::FILE_TEST_EXISTS) == false;
538 }