update JACK backend to use new inheritance structure for AudioBackend
[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 <cstdlib>
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 #include <time.h>
33
34 #ifdef WINDOWS_VST_SUPPORT
35 #include <fst.h>
36 #endif
37
38 #ifdef LXVST_SUPPORT
39 #include "ardour/linux_vst_support.h"
40 #endif
41
42 #ifdef AUDIOUNIT_SUPPORT
43 #include "ardour/audio_unit.h"
44 #endif
45
46 #ifdef __SSE__
47 #include <xmmintrin.h>
48 #endif
49
50 #ifdef check
51 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
52 #endif 
53
54 #include <glibmm/fileutils.h>
55 #include <glibmm/miscutils.h>
56
57 #include <lrdf.h>
58
59 #include "pbd/cpus.h"
60 #include "pbd/error.h"
61 #include "pbd/id.h"
62 #include "pbd/pbd.h"
63 #include "pbd/strsplit.h"
64 #include "pbd/fpu.h"
65 #include "pbd/file_utils.h"
66 #include "pbd/enumwriter.h"
67 #include "pbd/basename.h"
68
69 #include "midi++/port.h"
70 #include "midi++/mmc.h"
71
72 #include "ardour/analyser.h"
73 #include "ardour/audio_library.h"
74 #include "ardour/audio_backend.h"
75 #include "ardour/audioengine.h"
76 #include "ardour/audioplaylist.h"
77 #include "ardour/audioregion.h"
78 #include "ardour/buffer_manager.h"
79 #include "ardour/control_protocol_manager.h"
80 #include "ardour/filesystem_paths.h"
81 #include "ardour/midi_region.h"
82 #include "ardour/midiport_manager.h"
83 #include "ardour/mix.h"
84 #include "ardour/panner_manager.h"
85 #include "ardour/plugin_manager.h"
86 #include "ardour/process_thread.h"
87 #include "ardour/profile.h"
88 #include "ardour/rc_configuration.h"
89 #include "ardour/region.h"
90 #include "ardour/route_group.h"
91 #include "ardour/runtime_functions.h"
92 #include "ardour/session_event.h"
93 #include "ardour/source_factory.h"
94
95 #include "audiographer/routines.h"
96
97 #if defined (__APPLE__)
98        #include <Carbon/Carbon.h> // For Gestalt
99 #endif
100
101 #include "i18n.h"
102
103 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
104 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
105 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
106
107 using namespace ARDOUR;
108 using namespace std;
109 using namespace PBD;
110
111 bool libardour_initialized = false;
112
113 compute_peak_t          ARDOUR::compute_peak = 0;
114 find_peaks_t            ARDOUR::find_peaks = 0;
115 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
116 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
117 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
118
119 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
120 PBD::Signal0<void> ARDOUR::GUIIdle;
121
122 namespace ARDOUR {
123 extern void setup_enum_writer ();
124 }
125
126 /* this is useful for quite a few things that want to check
127    if any bounds-related property has changed
128 */
129 PBD::PropertyChange ARDOUR::bounds_change;
130
131 void
132 setup_hardware_optimization (bool try_optimization)
133 {
134         bool generic_mix_functions = true;
135
136         if (try_optimization) {
137
138                 FPU fpu;
139
140 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
141
142                 if (fpu.has_sse()) {
143
144                         info << "Using SSE optimized routines" << endmsg;
145
146                         // SSE SET
147                         compute_peak          = x86_sse_compute_peak;
148                         find_peaks            = x86_sse_find_peaks;
149                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
150                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
151                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
152
153                         generic_mix_functions = false;
154
155                 }
156
157 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
158                 SInt32 sysVersion = 0;
159
160                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
161                         sysVersion = 0;
162
163                 if (sysVersion >= 0x00001040) { // Tiger at least
164                         compute_peak           = veclib_compute_peak;
165                         find_peaks             = veclib_find_peaks;
166                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
167                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
168                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
169
170                         generic_mix_functions = false;
171
172                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
173                 }
174 #endif
175
176                 /* consider FPU denormal handling to be "h/w optimization" */
177
178                 setup_fpu ();
179         }
180
181         if (generic_mix_functions) {
182
183                 compute_peak          = default_compute_peak;
184                 find_peaks            = default_find_peaks;
185                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
186                 mix_buffers_with_gain = default_mix_buffers_with_gain;
187                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
188
189                 info << "No H/W specific optimizations in use" << endmsg;
190         }
191
192         AudioGrapher::Routines::override_compute_peak (compute_peak);
193         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
194 }
195
196 static void
197 lotsa_files_please ()
198 {
199         struct rlimit rl;
200
201         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
202
203                 rl.rlim_cur = rl.rlim_max;
204
205                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
206                         if (rl.rlim_cur == RLIM_INFINITY) {
207                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
208                         } else {
209                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
210                         }
211                 } else {
212                         if (rl.rlim_cur != RLIM_INFINITY) {
213                                 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
214                         }
215                 }
216         } else {
217                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
218         }
219 }
220
221 bool
222 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
223 {
224         if (libardour_initialized) {
225                 return true;
226         }
227
228         if (!PBD::init()) return false;
229
230 #ifdef ENABLE_NLS
231         (void) bindtextdomain(PACKAGE, localedir);
232 #endif
233
234         SessionEvent::init_event_pool ();
235
236         SessionObject::make_property_quarks ();
237         Region::make_property_quarks ();
238         MidiRegion::make_property_quarks ();
239         AudioRegion::make_property_quarks ();
240         RouteGroup::make_property_quarks ();
241         Playlist::make_property_quarks ();
242         AudioPlaylist::make_property_quarks ();
243
244         /* this is a useful ready to use PropertyChange that many
245            things need to check. This avoids having to compose
246            it every time we want to check for any of the relevant
247            property changes.
248         */
249
250         bounds_change.add (ARDOUR::Properties::start);
251         bounds_change.add (ARDOUR::Properties::position);
252         bounds_change.add (ARDOUR::Properties::length);
253
254         /* provide a state version for the few cases that need it and are not
255            driven by reading state from disk (e.g. undo/redo)
256         */
257
258         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
259
260         ARDOUR::setup_enum_writer ();
261
262         // allow ardour the absolute maximum number of open files
263         lotsa_files_please ();
264
265         lrdf_init();
266         Library = new AudioLibrary;
267
268         BootMessage (_("Loading configuration"));
269
270         Config = new RCConfiguration;
271
272         if (Config->load_state ()) {
273                 return false;
274         }
275
276         Config->set_use_windows_vst (use_windows_vst);
277 #ifdef LXVST_SUPPORT
278         Config->set_use_lxvst(true);
279 #endif
280
281         Profile = new RuntimeProfile;
282
283
284 #ifdef WINDOWS_VST_SUPPORT
285         if (Config->get_use_windows_vst() && fst_init (0)) {
286                 return false;
287         }
288 #endif
289
290 #ifdef LXVST_SUPPORT
291         if (Config->get_use_lxvst() && vstfx_init (0)) {
292                 return false;
293         }
294 #endif
295
296 #ifdef AUDIOUNIT_SUPPORT
297         AUPluginInfo::load_cached_info ();
298 #endif
299
300         setup_hardware_optimization (try_optimization);
301
302         SourceFactory::init ();
303         Analyser::init ();
304
305         /* singleton - first object is "it" */
306         (void) PluginManager::instance();
307
308         ProcessThread::init ();
309         /* the + 4 is a bit of a handwave. i don't actually know
310            how many more per-thread buffer sets we need above
311            the h/w concurrency, but its definitely > 1 more.
312         */
313         BufferManager::init (hardware_concurrency() + 4); 
314
315         PannerManager::instance().discover_panners();
316
317         // Initialize parameter metadata
318         EventTypeMap::instance().new_parameter(NullAutomation);
319         EventTypeMap::instance().new_parameter(GainAutomation);
320         EventTypeMap::instance().new_parameter(PanAzimuthAutomation);
321         EventTypeMap::instance().new_parameter(PanElevationAutomation);
322         EventTypeMap::instance().new_parameter(PanWidthAutomation);
323         EventTypeMap::instance().new_parameter(PluginAutomation);
324         EventTypeMap::instance().new_parameter(SoloAutomation);
325         EventTypeMap::instance().new_parameter(MuteAutomation);
326         EventTypeMap::instance().new_parameter(MidiCCAutomation);
327         EventTypeMap::instance().new_parameter(MidiPgmChangeAutomation);
328         EventTypeMap::instance().new_parameter(MidiPitchBenderAutomation);
329         EventTypeMap::instance().new_parameter(MidiChannelPressureAutomation);
330         EventTypeMap::instance().new_parameter(FadeInAutomation);
331         EventTypeMap::instance().new_parameter(FadeOutAutomation);
332         EventTypeMap::instance().new_parameter(EnvelopeAutomation);
333         EventTypeMap::instance().new_parameter(MidiCCAutomation);
334
335         ARDOUR::AudioEngine::create ();
336
337         libardour_initialized = true;
338
339         return true;
340 }
341
342 void
343 ARDOUR::init_post_engine ()
344 {
345         ControlProtocolManager::instance().discover_control_protocols ();
346
347         XMLNode* node;
348         if ((node = Config->control_protocol_state()) != 0) {
349                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
350         }
351
352         /* find plugins */
353
354         ARDOUR::PluginManager::instance().refresh ();
355 }
356
357 int
358 ARDOUR::cleanup ()
359 {
360         delete Library;
361         lrdf_cleanup ();
362         delete &ControlProtocolManager::instance();
363 #ifdef WINDOWS_VST_SUPPORT
364         fst_exit ();
365 #endif
366
367 #ifdef LXVST_SUPPORT
368         vstfx_exit();
369 #endif
370         PBD::cleanup ();
371         return 0;
372 }
373
374 void
375 ARDOUR::find_bindings_files (map<string,string>& files)
376 {
377         vector<std::string> found;
378         SearchPath spath = ardour_config_search_path();
379
380         if (getenv ("ARDOUR_SAE")) {
381                 Glib::PatternSpec pattern("*SAE-*.bindings");
382                 find_matching_files_in_search_path (spath, pattern, found);
383         } else {
384                 Glib::PatternSpec pattern("*.bindings");
385                 find_matching_files_in_search_path (spath, pattern, found);
386         }
387
388         if (found.empty()) {
389                 return;
390         }
391
392         for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
393                 std::string path(*x);
394                 pair<string,string> namepath;
395                 namepath.second = path;
396                 namepath.first = PBD::basename_nosuffix (path);
397                 files.insert (namepath);
398         }
399 }
400
401 bool
402 ARDOUR::no_auto_connect()
403 {
404         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
405 }
406
407 void
408 ARDOUR::setup_fpu ()
409 {
410
411         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
412                 // valgrind doesn't understand this assembler stuff
413                 // September 10th, 2007
414                 return;
415         }
416
417 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
418
419         int MXCSR;
420         FPU fpu;
421
422         /* XXX use real code to determine if the processor supports
423            DenormalsAreZero and FlushToZero
424         */
425
426         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
427                 return;
428         }
429
430         MXCSR  = _mm_getcsr();
431
432 #ifdef DEBUG_DENORMAL_EXCEPTION
433         /* This will raise a FP exception if a denormal is detected */
434         MXCSR &= ~_MM_MASK_DENORM;
435 #endif  
436
437         switch (Config->get_denormal_model()) {
438         case DenormalNone:
439                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
440                 break;
441
442         case DenormalFTZ:
443                 if (fpu.has_flush_to_zero()) {
444                         MXCSR |= _MM_FLUSH_ZERO_ON;
445                 }
446                 break;
447
448         case DenormalDAZ:
449                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
450                 if (fpu.has_denormals_are_zero()) {
451                         MXCSR |= 0x40;
452                 }
453                 break;
454
455         case DenormalFTZDAZ:
456                 if (fpu.has_flush_to_zero()) {
457                         if (fpu.has_denormals_are_zero()) {
458                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
459                         } else {
460                                 MXCSR |= _MM_FLUSH_ZERO_ON;
461                         }
462                 }
463                 break;
464         }
465
466         _mm_setcsr (MXCSR);
467
468 #endif
469 }
470
471 /* this can be changed to modify the translation behaviour for
472    cases where the user has never expressed a preference.
473 */
474 static const bool translate_by_default = true;
475
476 string
477 ARDOUR::translation_enable_path ()
478 {
479         return Glib::build_filename (user_config_directory(), ".translate");
480 }
481
482 bool
483 ARDOUR::translations_are_enabled ()
484 {
485         int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
486
487         if (fd < 0) {
488                 return translate_by_default;
489         }
490
491         char c;
492         bool ret = false;
493
494         if (::read (fd, &c, 1) == 1 && c == '1') {
495                 ret = true;
496         }
497
498         ::close (fd);
499
500         return ret;
501 }
502
503 bool
504 ARDOUR::set_translations_enabled (bool yn)
505 {
506         string i18n_enabler = ARDOUR::translation_enable_path();
507         int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
508
509         if (fd < 0) {
510                 return false;
511         }
512         
513         char c;
514         
515         if (yn) {
516                 c = '1';
517         } else {
518                 c = '0';
519         }
520         
521         ::write (fd, &c, 1);
522         ::close (fd);
523
524         return true;
525 }
526
527
528 vector<SyncSource>
529 ARDOUR::get_available_sync_options ()
530 {
531         vector<SyncSource> ret;
532
533         ret.push_back (JACK);
534         ret.push_back (MTC);
535         ret.push_back (MIDIClock);
536         ret.push_back (LTC);
537
538         return ret;
539 }
540
541 /** Return a monotonic value for the number of microseconds that have elapsed
542  * since an arbitrary zero origin.
543  */
544
545 #ifdef __MACH__
546 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
547  */
548 #include <mach/mach_time.h>
549 #define CLOCK_REALTIME 0
550 #define CLOCK_MONOTONIC 0
551 int 
552 clock_gettime (int /*clk_id*/, struct timespec *t)
553 {
554         static bool initialized = false;
555         static mach_timebase_info_data_t timebase;
556         if (!initialized) {
557                 mach_timebase_info(&timebase);
558                 initialized = true;
559         }
560         uint64_t time;
561         time = mach_absolute_time();
562         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
563         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
564         t->tv_sec = seconds;
565         t->tv_nsec = nseconds;
566         return 0;
567 }
568 #endif
569  
570 microseconds_t
571 ARDOUR::get_microseconds ()
572 {
573         struct timespec ts;
574         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
575                 /* EEEK! */
576                 return 0;
577         }
578         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
579 }