Implement 2532: option to show tracks with regions under the playhead.
[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
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <sys/resource.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <errno.h>
32
33 #ifdef VST_SUPPORT
34 #include <fst.h>
35 #endif
36
37 #ifdef HAVE_AUDIOUNITS
38 #include "ardour/audio_unit.h"
39 #endif
40
41 #ifdef __SSE__
42 #include <xmmintrin.h>
43 #endif
44
45 #include <glibmm/fileutils.h>
46 #include <glibmm/miscutils.h>
47
48 #include <lrdf.h>
49
50 #include "pbd/error.h"
51 #include "pbd/id.h"
52 #include "pbd/strsplit.h"
53 #include "pbd/fpu.h"
54 #include "pbd/file_utils.h"
55 #include "pbd/enumwriter.h"
56
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
59 #include "midi++/mmc.h"
60
61 #include "ardour/analyser.h"
62 #include "ardour/ardour.h"
63 #include "ardour/audio_library.h"
64 #include "ardour/audioengine.h"
65 #include "ardour/audiosource.h"
66 #include "ardour/control_protocol_manager.h"
67 #include "ardour/debug.h"
68 #include "ardour/filesystem_paths.h"
69 #include "ardour/mix.h"
70 #include "ardour/plugin_manager.h"
71 #include "ardour/profile.h"
72 #include "ardour/rc_configuration.h"
73 #include "ardour/runtime_functions.h"
74 #include "ardour/session.h"
75 #include "ardour/source_factory.h"
76 #include "ardour/utils.h"
77
78 #if defined (__APPLE__)
79        #include <Carbon/Carbon.h> // For Gestalt
80 #endif
81
82 #include "i18n.h"
83
84 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
85 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
86 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
87
88 using namespace ARDOUR;
89 using namespace std;
90 using namespace PBD;
91
92 uint64_t ARDOUR::debug_bits = 0x0;
93
94 MIDI::Port *ARDOUR::default_mmc_port = 0;
95 MIDI::Port *ARDOUR::default_mtc_port = 0;
96 MIDI::Port *ARDOUR::default_midi_port = 0;
97 MIDI::Port *ARDOUR::default_midi_clock_port = 0;
98
99 Change ARDOUR::StartChanged = ARDOUR::new_change ();
100 Change ARDOUR::LengthChanged = ARDOUR::new_change ();
101 Change ARDOUR::PositionChanged = ARDOUR::new_change ();
102 Change ARDOUR::NameChanged = ARDOUR::new_change ();
103 Change ARDOUR::BoundsChanged = Change (0); // see init(), below
104
105 compute_peak_t          ARDOUR::compute_peak = 0;
106 find_peaks_t            ARDOUR::find_peaks = 0;
107 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
108 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
109 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
110
111 sigc::signal<void,std::string> ARDOUR::BootMessage;
112
113 void
114 ARDOUR::debug_print (const char* prefix, std::string str)
115 {
116         cerr << prefix << ": " << str;
117 }
118
119 void
120 ARDOUR::set_debug_bits (uint64_t bits)
121 {
122         debug_bits = bits;
123 }
124
125 int
126 ARDOUR::setup_midi ()
127 {
128         if (Config->midi_ports.size() == 0) {
129                 return 0;
130         }
131
132         BootMessage (_("Configuring MIDI ports"));
133
134         for (std::map<string,XMLNode>::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
135                 MIDI::Manager::instance()->add_port (i->second);
136         }
137
138         MIDI::Port* first;
139         const MIDI::Manager::PortList& ports = MIDI::Manager::instance()->get_midi_ports();
140
141         if (ports.size() > 1) {
142
143                 first = ports.front();
144
145                 /* More than one port, so try using specific names for each port */
146
147                 default_mmc_port =  MIDI::Manager::instance()->port (Config->get_mmc_port_name());
148                 default_mtc_port =  MIDI::Manager::instance()->port (Config->get_mtc_port_name());
149                 default_midi_port =  MIDI::Manager::instance()->port (Config->get_midi_port_name());
150                 default_midi_clock_port =  MIDI::Manager::instance()->port (Config->get_midi_clock_port_name());
151
152                 /* If that didn't work, just use the first listed port */
153
154                 if (default_mmc_port == 0) {
155                         default_mmc_port = first;
156                 }
157
158                 if (default_mtc_port == 0) {
159                         default_mtc_port = first;
160                 }
161
162                 if (default_midi_port == 0) {
163                         default_midi_port = first;
164                 }
165
166                 if (default_midi_clock_port == 0) {
167                         default_midi_clock_port = first;
168                 }
169
170         } else if (ports.size() == 1) {
171
172                 first = ports.front();
173
174                 /* Only one port described, so use it for both MTC and MMC */
175
176                 default_mmc_port = first;
177                 default_mtc_port = default_mmc_port;
178                 default_midi_port = default_mmc_port;
179                 default_midi_clock_port = default_mmc_port;
180         }
181
182         if (default_mmc_port == 0) {
183                 warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name())
184                         << endmsg;
185         }
186
187
188         if (default_mtc_port == 0) {
189                 warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name())
190                         << endmsg;
191         }
192
193         if (default_midi_port == 0) {
194                 warning << string_compose (_("No MIDI parameter support (MIDI port \"%1\" not available)"), Config->get_midi_port_name())
195                         << endmsg;
196         }
197
198         if (default_midi_clock_port == 0) {
199                 warning << string_compose (_("No MIDI Clock support (MIDI port \"%1\" not available)"), Config->get_midi_clock_port_name())
200                         << endmsg;
201         }
202
203         return 0;
204 }
205
206 void
207 setup_hardware_optimization (bool try_optimization)
208 {
209         bool generic_mix_functions = true;
210
211         if (try_optimization) {
212
213                 FPU fpu;
214
215 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
216
217                 if (fpu.has_sse()) {
218
219                         info << "Using SSE optimized routines" << endmsg;
220
221                         // SSE SET
222                         compute_peak          = x86_sse_compute_peak;
223                         find_peaks            = x86_sse_find_peaks;
224                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
225                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
226                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
227
228                         generic_mix_functions = false;
229
230                 }
231
232 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
233                 long sysVersion = 0;
234
235                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
236                         sysVersion = 0;
237
238                 if (sysVersion >= 0x00001040) { // Tiger at least
239                         compute_peak           = veclib_compute_peak;
240                         find_peaks             = veclib_find_peaks;
241                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
242                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
243                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
244
245                         generic_mix_functions = false;
246
247                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
248                 }
249 #endif
250
251                 /* consider FPU denormal handling to be "h/w optimization" */
252
253                 setup_fpu ();
254         }
255
256         if (generic_mix_functions) {
257
258                 compute_peak          = default_compute_peak;
259                 find_peaks            = default_find_peaks;
260                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
261                 mix_buffers_with_gain = default_mix_buffers_with_gain;
262                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
263
264                 info << "No H/W specific optimizations in use" << endmsg;
265         }
266 }
267
268 static void
269 lotsa_files_please ()
270 {
271         struct rlimit rl;
272
273         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
274
275                 rl.rlim_cur = rl.rlim_max;
276
277                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
278                         if (rl.rlim_cur == RLIM_INFINITY) {
279                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
280                         } else {
281                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
282                         }
283                 } else {
284                         if (rl.rlim_cur == RLIM_INFINITY) {
285                                 info << _("Removed open file count limit. Excellent!") << endmsg;
286                         } else {
287                                 info << string_compose (_("Ardour will be limited to %1 open files"), rl.rlim_cur) << endmsg;
288                         }
289                 }
290         } else {
291                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
292         }
293 }
294
295 int
296 ARDOUR::init (bool use_vst, bool try_optimization)
297 {
298         if (!Glib::thread_supported())
299                 Glib::thread_init();
300
301         PBD::ID::init ();
302
303         extern void setup_enum_writer ();
304
305         (void) bindtextdomain(PACKAGE, LOCALEDIR);
306
307         /* provide a state version for the few cases that need it and are not
308            driven by reading state from disk (e.g. undo/redo)
309         */
310
311         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
312
313         setup_enum_writer ();
314
315         // allow ardour the absolute maximum number of open files
316         lotsa_files_please ();
317
318         lrdf_init();
319         Library = new AudioLibrary;
320
321         BootMessage (_("Loading configuration"));
322
323         Config = new RCConfiguration;
324
325         if (Config->load_state ()) {
326                 return -1;
327         }
328
329         
330         Config->set_use_vst (use_vst);
331
332         cerr << "After config loaded, MTC port name = " << Config->get_mtc_port_name() << endl;
333
334         Profile = new RuntimeProfile;
335
336
337 #ifdef VST_SUPPORT
338         if (Config->get_use_vst() && fst_init (0)) {
339                 return -1;
340         }
341 #endif
342
343 #ifdef HAVE_AUDIOUNITS
344         AUPluginInfo::load_cached_info ();
345 #endif
346
347         /* Make VAMP look in our library ahead of anything else */
348
349         char *p = getenv ("VAMP_PATH");
350         string vamppath = VAMP_DIR;
351         if (p) {
352                 vamppath += ':';
353                 vamppath += p;
354         }
355         setenv ("VAMP_PATH", vamppath.c_str(), 1);
356
357
358         setup_hardware_optimization (try_optimization);
359
360         SourceFactory::init ();
361         Analyser::init ();
362
363         /* singleton - first object is "it" */
364         new PluginManager ();
365
366         BoundsChanged = Change (StartChanged|PositionChanged|LengthChanged);
367
368         return 0;
369 }
370
371 void
372 ARDOUR::init_post_engine ()
373 {
374         ControlProtocolManager::instance().discover_control_protocols ();
375
376         XMLNode* node;
377         if ((node = Config->control_protocol_state()) != 0) {
378                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
379         }
380 }
381
382 int
383 ARDOUR::cleanup ()
384 {
385         delete Library;
386         lrdf_cleanup ();
387         delete &ControlProtocolManager::instance();
388 #ifdef VST_SUPPORT
389         fst_exit ();
390 #endif
391         return 0;
392 }
393
394 ARDOUR::Change
395 ARDOUR::new_change ()
396 {
397         Change c;
398         static uint32_t change_bit = 1;
399
400         /* catch out-of-range */
401         if (!change_bit)
402         {
403                 fatal << _("programming error: ")
404                         << "change_bit out of range in ARDOUR::new_change()"
405                         << endmsg;
406                 /*NOTREACHED*/
407         }
408
409         c = Change (change_bit);
410         change_bit <<= 1;       // if it shifts too far, change_bit == 0
411
412         return c;
413 }
414
415 string
416 ARDOUR::get_ardour_revision ()
417 {
418         return "$Rev$";
419 }
420
421 void
422 ARDOUR::find_bindings_files (map<string,string>& files)
423 {
424         vector<sys::path> found;
425         SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
426
427         if (getenv ("ARDOUR_SAE")) {
428                 Glib::PatternSpec pattern("*SAE-*.bindings");
429                 find_matching_files_in_search_path (spath, pattern, found);
430         } else {
431                 Glib::PatternSpec pattern("*.bindings");
432                 find_matching_files_in_search_path (spath, pattern, found);
433         }
434
435         if (found.empty()) {
436                 return;
437         }
438
439         for (vector<sys::path>::iterator x = found.begin(); x != found.end(); ++x) {
440                 sys::path path = *x;
441                 pair<string,string> namepath;
442                 namepath.second = path.to_string();
443                 namepath.first = path.leaf().substr (0, path.leaf().find_first_of ('.'));
444                 files.insert (namepath);
445         }
446 }
447
448 bool
449 ARDOUR::no_auto_connect()
450 {
451         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
452 }
453
454 void
455 ARDOUR::setup_fpu ()
456 {
457
458         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
459                 // valgrind doesn't understand this assembler stuff
460                 // September 10th, 2007
461                 return;
462         }
463
464 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
465
466         int MXCSR;
467         FPU fpu;
468
469         /* XXX use real code to determine if the processor supports
470            DenormalsAreZero and FlushToZero
471         */
472
473         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
474                 return;
475         }
476
477         MXCSR  = _mm_getcsr();
478
479         switch (Config->get_denormal_model()) {
480         case DenormalNone:
481                 MXCSR &= ~(_MM_FLUSH_ZERO_ON|0x8000);
482                 break;
483
484         case DenormalFTZ:
485                 if (fpu.has_flush_to_zero()) {
486                         MXCSR |= _MM_FLUSH_ZERO_ON;
487                 }
488                 break;
489
490         case DenormalDAZ:
491                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
492                 if (fpu.has_denormals_are_zero()) {
493                         MXCSR |= 0x8000;
494                 }
495                 break;
496
497         case DenormalFTZDAZ:
498                 if (fpu.has_flush_to_zero()) {
499                         if (fpu.has_denormals_are_zero()) {
500                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000;
501                         } else {
502                                 MXCSR |= _MM_FLUSH_ZERO_ON;
503                         }
504                 }
505                 break;
506         }
507
508         _mm_setcsr (MXCSR);
509
510 #endif
511 }
512
513 ARDOUR::OverlapType
514 ARDOUR::coverage (nframes_t sa, nframes_t ea,
515                   nframes_t sb, nframes_t eb)
516 {
517         /* OverlapType returned reflects how the second (B)
518            range overlaps the first (A).
519
520            The diagrams show various relative placements
521            of A and B for each OverlapType.
522
523            Notes:
524               Internal: the start points cannot coincide
525               External: the start and end points can coincide
526               Start: end points can coincide
527               End: start points can coincide
528
529            XXX Logically, Internal should disallow end
530            point equality.
531         */
532
533         /*
534              |--------------------|   A
535                   |------|            B
536                 |-----------------|   B
537
538
539              "B is internal to A"
540
541         */
542 #ifdef OLD_COVERAGE
543         if ((sb >= sa) && (eb <= ea)) {
544 #else
545         if ((sb > sa) && (eb <= ea)) {
546 #endif
547                 return OverlapInternal;
548         }
549
550         /*
551              |--------------------|   A
552            ----|                      B
553            -----------------------|   B
554            --|                        B
555
556              "B overlaps the start of A"
557
558         */
559
560         if ((eb >= sa) && (eb <= ea)) {
561                 return OverlapStart;
562         }
563         /*
564              |---------------------|  A
565                    |----------------- B
566              |----------------------- B
567                                    |- B
568
569             "B overlaps the end of A"
570
571         */
572         if ((sb > sa) && (sb <= ea)) {
573                 return OverlapEnd;
574         }
575         /*
576              |--------------------|     A
577            --------------------------  B
578              |-----------------------  B
579             ----------------------|    B
580              |--------------------|    B
581
582
583            "B overlaps all of A"
584         */
585         if ((sa >= sb) && (sa <= eb) && (ea <= eb)) {
586                 return OverlapExternal;
587         }
588
589         return OverlapNone;
590 }
591