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