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