Yamaha-PSR-S900.midnam: correct organ flutes, duplicate settings generated from fault...
[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 WINDOWS_VST_SUPPORT
33 #include <fst.h>
34 #endif
35
36 #ifdef LXVST_SUPPORT
37 #include "ardour/linux_vst_support.h"
38 #endif
39
40 #ifdef AUDIOUNIT_SUPPORT
41 #include "ardour/audio_unit.h"
42 #endif
43
44 #ifdef __SSE__
45 #include <xmmintrin.h>
46 #endif
47
48 #ifdef check
49 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
50 #endif 
51
52 #include <giomm.h>
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/strsplit.h"
63 #include "pbd/fpu.h"
64 #include "pbd/file_utils.h"
65 #include "pbd/enumwriter.h"
66 #include "pbd/basename.h"
67
68 #include "midi++/port.h"
69 #include "midi++/manager.h"
70 #include "midi++/mmc.h"
71
72 #include "ardour/analyser.h"
73 #include "ardour/audio_library.h"
74 #include "ardour/audioengine.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/buffer_manager.h"
78 #include "ardour/control_protocol_manager.h"
79 #include "ardour/filesystem_paths.h"
80 #include "ardour/midi_region.h"
81 #include "ardour/mix.h"
82 #include "ardour/panner_manager.h"
83 #include "ardour/plugin_manager.h"
84 #include "ardour/process_thread.h"
85 #include "ardour/profile.h"
86 #include "ardour/rc_configuration.h"
87 #include "ardour/region.h"
88 #include "ardour/route_group.h"
89 #include "ardour/runtime_functions.h"
90 #include "ardour/session_event.h"
91 #include "ardour/source_factory.h"
92
93 #include "audiographer/routines.h"
94
95 #if defined (__APPLE__)
96        #include <Carbon/Carbon.h> // For Gestalt
97 #endif
98
99 #include "i18n.h"
100
101 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
102 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
103 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
104
105 using namespace ARDOUR;
106 using namespace std;
107 using namespace PBD;
108
109 compute_peak_t          ARDOUR::compute_peak = 0;
110 find_peaks_t            ARDOUR::find_peaks = 0;
111 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
112 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
113 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
114
115 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
116
117 namespace ARDOUR {
118 extern void setup_enum_writer ();
119 }
120
121 /* this is useful for quite a few things that want to check
122    if any bounds-related property has changed
123 */
124 PBD::PropertyChange ARDOUR::bounds_change;
125
126 void
127 setup_hardware_optimization (bool try_optimization)
128 {
129         bool generic_mix_functions = true;
130
131         if (try_optimization) {
132
133                 FPU fpu;
134
135 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
136
137                 if (fpu.has_sse()) {
138
139                         info << "Using SSE optimized routines" << endmsg;
140
141                         // SSE SET
142                         compute_peak          = x86_sse_compute_peak;
143                         find_peaks            = x86_sse_find_peaks;
144                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
145                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
146                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
147
148                         generic_mix_functions = false;
149
150                 }
151
152 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
153                 SInt32 sysVersion = 0;
154
155                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
156                         sysVersion = 0;
157
158                 if (sysVersion >= 0x00001040) { // Tiger at least
159                         compute_peak           = veclib_compute_peak;
160                         find_peaks             = veclib_find_peaks;
161                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
162                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
163                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
164
165                         generic_mix_functions = false;
166
167                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
168                 }
169 #endif
170
171                 /* consider FPU denormal handling to be "h/w optimization" */
172
173                 setup_fpu ();
174         }
175
176         if (generic_mix_functions) {
177
178                 compute_peak          = default_compute_peak;
179                 find_peaks            = default_find_peaks;
180                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
181                 mix_buffers_with_gain = default_mix_buffers_with_gain;
182                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
183
184                 info << "No H/W specific optimizations in use" << endmsg;
185         }
186
187         AudioGrapher::Routines::override_compute_peak (compute_peak);
188         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
189 }
190
191 static void
192 lotsa_files_please ()
193 {
194         struct rlimit rl;
195
196         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
197
198                 rl.rlim_cur = rl.rlim_max;
199
200                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
201                         if (rl.rlim_cur == RLIM_INFINITY) {
202                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
203                         } else {
204                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
205                         }
206                 } else {
207                         if (rl.rlim_cur == RLIM_INFINITY) {
208                                 info << _("Removed open file count limit. Excellent!") << endmsg;
209                         } else {
210                                 info << string_compose (_("%1 will be limited to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
211                         }
212                 }
213         } else {
214                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
215         }
216 }
217
218 int
219 ARDOUR::init (bool use_windows_vst, bool try_optimization)
220 {
221         if (!Glib::thread_supported()) {
222                 Glib::thread_init();
223         }
224
225         // this really should be in PBD::init..if there was one
226         Gio::init ();
227
228         (void) bindtextdomain(PACKAGE, LOCALEDIR);
229
230         PBD::ID::init ();
231         SessionEvent::init_event_pool ();
232
233         SessionObject::make_property_quarks ();
234         Region::make_property_quarks ();
235         MidiRegion::make_property_quarks ();
236         AudioRegion::make_property_quarks ();
237         RouteGroup::make_property_quarks ();
238         Playlist::make_property_quarks ();
239         AudioPlaylist::make_property_quarks ();
240
241         /* this is a useful ready to use PropertyChange that many
242            things need to check. This avoids having to compose
243            it every time we want to check for any of the relevant
244            property changes.
245         */
246
247         bounds_change.add (ARDOUR::Properties::start);
248         bounds_change.add (ARDOUR::Properties::position);
249         bounds_change.add (ARDOUR::Properties::length);
250
251         /* provide a state version for the few cases that need it and are not
252            driven by reading state from disk (e.g. undo/redo)
253         */
254
255         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
256
257         ARDOUR::setup_enum_writer ();
258
259         // allow ardour the absolute maximum number of open files
260         lotsa_files_please ();
261
262         lrdf_init();
263         Library = new AudioLibrary;
264
265         BootMessage (_("Loading configuration"));
266
267         Config = new RCConfiguration;
268
269         if (Config->load_state ()) {
270                 return -1;
271         }
272
273         Config->set_use_windows_vst (use_windows_vst);
274 #ifdef LXVST_SUPPORT
275         Config->set_use_lxvst(true);
276 #endif
277
278         Profile = new RuntimeProfile;
279
280
281 #ifdef WINDOWS_VST_SUPPORT
282         if (Config->get_use_windows_vst() && fst_init (0)) {
283                 return -1;
284         }
285 #endif
286
287 #ifdef LXVST_SUPPORT
288         if (Config->get_use_lxvst() && vstfx_init (0)) {
289                 return -1;
290         }
291 #endif
292
293 #ifdef AUDIOUNIT_SUPPORT
294         AUPluginInfo::load_cached_info ();
295 #endif
296
297         setup_hardware_optimization (try_optimization);
298
299         SourceFactory::init ();
300         Analyser::init ();
301
302         /* singleton - first object is "it" */
303         (void) PluginManager::instance();
304
305         ProcessThread::init ();
306         /* the + 4 is a bit of a handwave. i don't actually know
307            how many more per-thread buffer sets we need above
308            the h/w concurrency, but its definitely > 1 more.
309         */
310         BufferManager::init (hardware_concurrency() + 4); 
311
312         PannerManager::instance().discover_panners();
313
314         // Initialize parameter metadata
315         EventTypeMap::instance().new_parameter(NullAutomation);
316         EventTypeMap::instance().new_parameter(GainAutomation);
317         EventTypeMap::instance().new_parameter(PanAzimuthAutomation);
318         EventTypeMap::instance().new_parameter(PanElevationAutomation);
319         EventTypeMap::instance().new_parameter(PanWidthAutomation);
320         EventTypeMap::instance().new_parameter(PluginAutomation);
321         EventTypeMap::instance().new_parameter(SoloAutomation);
322         EventTypeMap::instance().new_parameter(MuteAutomation);
323         EventTypeMap::instance().new_parameter(MidiCCAutomation);
324         EventTypeMap::instance().new_parameter(MidiPgmChangeAutomation);
325         EventTypeMap::instance().new_parameter(MidiPitchBenderAutomation);
326         EventTypeMap::instance().new_parameter(MidiChannelPressureAutomation);
327         EventTypeMap::instance().new_parameter(FadeInAutomation);
328         EventTypeMap::instance().new_parameter(FadeOutAutomation);
329         EventTypeMap::instance().new_parameter(EnvelopeAutomation);
330         EventTypeMap::instance().new_parameter(MidiCCAutomation);
331
332         return 0;
333 }
334
335 void
336 ARDOUR::init_post_engine ()
337 {
338         /* the MIDI Manager is needed by the ControlProtocolManager */
339         MIDI::Manager::create (AudioEngine::instance()->jack());
340
341         ControlProtocolManager::instance().discover_control_protocols ();
342
343         XMLNode* node;
344         if ((node = Config->control_protocol_state()) != 0) {
345                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
346         }
347
348         /* find plugins */
349
350         ARDOUR::PluginManager::instance().refresh ();
351 }
352
353 int
354 ARDOUR::cleanup ()
355 {
356         delete Library;
357         lrdf_cleanup ();
358         delete &ControlProtocolManager::instance();
359 #ifdef WINDOWS_VST_SUPPORT
360         fst_exit ();
361 #endif
362
363 #ifdef LXVST_SUPPORT
364         vstfx_exit();
365 #endif
366         EnumWriter::destroy ();
367         return 0;
368 }
369
370 void
371 ARDOUR::find_bindings_files (map<string,string>& files)
372 {
373         vector<std::string> found;
374         SearchPath spath = ardour_config_search_path();
375
376         if (getenv ("ARDOUR_SAE")) {
377                 Glib::PatternSpec pattern("*SAE-*.bindings");
378                 find_matching_files_in_search_path (spath, pattern, found);
379         } else {
380                 Glib::PatternSpec pattern("*.bindings");
381                 find_matching_files_in_search_path (spath, pattern, found);
382         }
383
384         if (found.empty()) {
385                 return;
386         }
387
388         for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
389                 std::string path(*x);
390                 pair<string,string> namepath;
391                 namepath.second = path;
392                 namepath.first = PBD::basename_nosuffix (path);
393                 files.insert (namepath);
394         }
395 }
396
397 bool
398 ARDOUR::no_auto_connect()
399 {
400         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
401 }
402
403 void
404 ARDOUR::setup_fpu ()
405 {
406
407         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
408                 // valgrind doesn't understand this assembler stuff
409                 // September 10th, 2007
410                 return;
411         }
412
413 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
414
415         int MXCSR;
416         FPU fpu;
417
418         /* XXX use real code to determine if the processor supports
419            DenormalsAreZero and FlushToZero
420         */
421
422         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
423                 return;
424         }
425
426         MXCSR  = _mm_getcsr();
427
428 #ifdef DEBUG_DENORMAL_EXCEPTION
429         /* This will raise a FP exception if a denormal is detected */
430         MXCSR &= ~_MM_MASK_DENORM;
431 #endif  
432
433         switch (Config->get_denormal_model()) {
434         case DenormalNone:
435                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
436                 break;
437
438         case DenormalFTZ:
439                 if (fpu.has_flush_to_zero()) {
440                         MXCSR |= _MM_FLUSH_ZERO_ON;
441                 }
442                 break;
443
444         case DenormalDAZ:
445                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
446                 if (fpu.has_denormals_are_zero()) {
447                         MXCSR |= 0x40;
448                 }
449                 break;
450
451         case DenormalFTZDAZ:
452                 if (fpu.has_flush_to_zero()) {
453                         if (fpu.has_denormals_are_zero()) {
454                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
455                         } else {
456                                 MXCSR |= _MM_FLUSH_ZERO_ON;
457                         }
458                 }
459                 break;
460         }
461
462         _mm_setcsr (MXCSR);
463
464 #endif
465 }
466
467 string
468 ARDOUR::translation_kill_path ()
469 {
470         return Glib::build_filename (user_config_directory(), ".love_is_the_language_of_audio");
471 }
472
473 bool
474 ARDOUR::translations_are_disabled ()
475 {
476         /* if file does not exist, we don't translate (bundled ardour only) */
477         return Glib::file_test (translation_kill_path(), Glib::FILE_TEST_EXISTS) == false;
478 }