2nd stage of denormal handling (from trunk); fix to avoid FLAC support when using...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 1 Jun 2007 22:26:12 +0000 (22:26 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 1 Jun 2007 22:26:12 +0000 (22:26 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@1940 d708f5d6-7413-0410-9779-e7cbd77b26cf

SConstruct
gtk2_ardour/ardour.menus
gtk2_ardour/ardour_ui_ed.cc
libs/ardour/globals.cc
libs/ardour/session_state.cc
libs/pbd/SConscript
libs/pbd/fpu.cc [new file with mode: 0644]
libs/pbd/pbd/fpu.h [new file with mode: 0644]

index 15e4f1e9ca5a2e6cec5b6dfb163d664aca349f4e..4d0b6ef6774695698fc19b328f28e691dc60a9a2 100644 (file)
@@ -36,7 +36,6 @@ opts.AddOptions(
     BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic.  Might break compilation.  For pedants', 0),
     BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
     BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
-    BoolOption('USE_XMMINTRIN', 'Use gcc XMM intrinsics where possible', 1),
     BoolOption('LIBLO', 'Compile with support for liblo library', 1),
     BoolOption('NLS', 'Set to turn on i18n support', 1),
     PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
@@ -736,8 +735,14 @@ libraries['flac'] = LibraryInfo ()
 prep_libcheck(env, libraries['flac'])
 libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
 
+#
+# june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
+#                since the version of libsndfile we have internally does not support
+#                the new API that libFLAC has adopted
+#
+
 conf = Configure (libraries['flac'])
-if conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX'):
+if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_set_read_callback', language='CXX'):
     conf.env.Append(CCFLAGS='-DHAVE_FLAC')
 libraries['flac'] = conf.Finish ()
 
index bd4bb3a0a1bf21f1bda42a846a0f17a29b8046b9..b8c98bc7a984ff5da543ac8f7643d59a57a2eaaf 100644 (file)
                   <menuitem action='CrossfadesShort'/>
               </menu>
               <menu action='Layering'>
-                  <menuitem action='LayerLaterHigher'/>
-                  <menuitem action='LayerMoveAddHigher'/>
-                  <menuitem action='LayerAddHigher'/>
+                    <menuitem action='LayerLaterHigher'/>
+                    <menuitem action='LayerMoveAddHigher'/>
+                    <menuitem action='LayerAddHigher'/>
+              </menu>
+              <menu name='Denormals' action='Denormals'>
+                      <menuitem action='DenormalProtection'/>
+                     <separator/>
+                      <menuitem action='DenormalNone'/>
+                      <menuitem action='DenormalFTZ'/>
+                      <menuitem action='DenormalDAZ'/>
+                     <menuitem action='DenormalFTZDAZ'/>
                </menu>
                <separator/>
                <menuitem action='SendMTC'/>
                <menuitem action='StopRecordingOnXrun'/>
                <menuitem action='StopTransportAtEndOfSession'/>
                <menuitem action='GainReduceFastTransport'/>
-              <menu name='Denormals' action='Denormals'>
-                             <menuitem action='DenormalProtection'/>
-                             <menuitem action='DenormalNone'/>
-                             <menuitem action='DenormalFTZ'/>
-                             <menuitem action='DenormalDAZ'/>
-                             <menuitem action='DenormalFTZDAZ'/>
-                </menu>
+              <menuitem action='PrimaryClockDeltaEditCursor'/>
+              <menuitem action='SecondaryClockDeltaEditCursor'/>
          </menu>
         <menu name='Help' action='Help'>
             <menuitem action='About'/>
index 37e23cdf6e8ced25bd7a587341b7f48e1dd32696..0e54e6253ebca68011eaaa07988d1c72f5db72af 100644 (file)
@@ -24,6 +24,7 @@
 */
 
 #include <pbd/pathscanner.h>
+#include <pbd/fpu.h>
 
 #include <glibmm/miscutils.h>
 
@@ -413,11 +414,23 @@ ARDOUR_UI::install_actions ()
        RadioAction::Group denormal_group;
 
        ActionManager::register_toggle_action (option_actions, X_("DenormalProtection"), _("Use DC bias"), mem_fun (*this, &ARDOUR_UI::toggle_denormal_protection));
+       
+       FPU fpu;
 
        ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalNone"), _("No processor handling"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalNone));
-       ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZ"), _("Use FlushToZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZ));
-       ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalDAZ"), _("Use DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalDAZ));
-       ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZDAZ"), _("Use FlushToZero & DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZDAZ));
+
+       act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZ"), _("Use FlushToZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZ));
+       if (!fpu.has_flush_to_zero()) {
+               act->set_sensitive (false);
+       }
+       act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalDAZ"), _("Use DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalDAZ));
+       if (!fpu.has_denormals_are_zero()) {
+               act->set_sensitive (false);
+       }
+       act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZDAZ"), _("Use FlushToZero & DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZDAZ));
+       if (!fpu.has_flush_to_zero() || !fpu.has_denormals_are_zero()) {
+               act->set_sensitive (false);
+       }
 
        act = ActionManager::register_toggle_action (option_actions, X_("DoNotRunPluginsWhileRecording"), _("Do not run plugins while recording"), mem_fun (*this, &ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording));
        ActionManager::session_sensitive_actions.push_back (act);
index eb5a2cc9f287cf32913a9d77bdc349c0de7a5054..a6fb0fcf41c29d7908efe99206bfa5fba04354fb 100644 (file)
@@ -37,6 +37,7 @@
 #include <pbd/error.h>
 #include <pbd/id.h>
 #include <pbd/strsplit.h>
+#include <pbd/fpu.h>
 
 #include <midi++/port.h>
 #include <midi++/port_request.h>
@@ -200,42 +201,14 @@ void
 setup_hardware_optimization (bool try_optimization)
 {
         bool generic_mix_functions = true;
-
+       FPU fpu;
 
        if (try_optimization) {
 
 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
-       
-               unsigned long use_sse = 0;
-
-#ifndef USE_X86_64_ASM
-               asm (
-                                "mov $1, %%eax\n"
-                                "pushl %%ebx\n"
-                                "cpuid\n"
-                                "movl %%edx, %0\n"
-                                "popl %%ebx\n"
-                            : "=r" (use_sse)
-                            : 
-                        : "%eax", "%ecx", "%edx", "memory");
-
-#else
-
-               asm (
-                                "pushq %%rbx\n"
-                                "movq $1, %%rax\n"
-                                "cpuid\n"
-                                "movq %%rdx, %0\n"
-                                "popq %%rbx\n"
-                            : "=r" (use_sse)
-                            : 
-                        : "%rax", "%rcx", "%rdx", "memory");
-
-#endif /* USE_X86_64_ASM */
-
-               use_sse &= (1 << 25); // bit 25 = SSE support
+               
+               if (fpu.has_sse()) {
 
-               if (use_sse) {
                        info << "Using SSE optimized routines" << endmsg;
        
                        // SSE SET
@@ -538,17 +511,16 @@ ARDOUR::LocaleGuard::~LocaleGuard ()
 void
 ARDOUR::setup_fpu ()
 {
-#ifdef USE_XMMINTRIN
+#if defined(ARCH_X86) && defined(USE_XMMINTRIN)
+
        int MXCSR;
+       FPU fpu;
 
        /* XXX use real code to determine if the processor supports
           DenormalsAreZero and FlushToZero
        */
        
-       bool has_daz = false;
-       bool can_ftz = true;
-
-       if (!can_ftz && !has_daz) {
+       if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
                return;
        }
 
@@ -556,25 +528,29 @@ ARDOUR::setup_fpu ()
 
        switch (Config->get_denormal_model()) {
        case DenormalNone:
-               MXCSR &= ~_MM_FLUSH_ZERO_ON;
+               MXCSR &= ~(_MM_FLUSH_ZERO_ON|0x8000);
                break;
 
        case DenormalFTZ:
-               MXCSR |= _MM_FLUSH_ZERO_ON;
+               if (fpu.has_flush_to_zero()) {
+                       MXCSR |= _MM_FLUSH_ZERO_ON;
+               }
                break;
 
        case DenormalDAZ:
                MXCSR &= ~_MM_FLUSH_ZERO_ON;
-               if (has_daz) {
+               if (fpu.has_denormals_are_zero()) {
                        MXCSR |= 0x8000;
                }
                break;
                
        case DenormalFTZDAZ:
-               if (has_daz) {
-                       MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000;
-               } else {
-                       MXCSR |= _MM_FLUSH_ZERO_ON;
+               if (fpu.has_flush_to_zero()) {
+                       if (fpu.has_denormals_are_zero()) {
+                               MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000;
+                       } else {
+                               MXCSR |= _MM_FLUSH_ZERO_ON;
+                       }
                }
                break;
        }
index 937fd78daf69854ad771932f5639b79f4bd9c203..37b717f49157b5567f6b5453d60da151b72caa9c 100644 (file)
@@ -3278,6 +3278,8 @@ Session::config_changed (const char* parameter_name)
                set_slave_source (Config->get_slave_source());
        } else if (PARAM_IS ("remote-model")) {
                set_remote_control_ids ();
+       }  else if (PARAM_IS ("denormal-model")) {
+               setup_fpu ();
        }
 
        set_dirty ();
index 3aaeb1bf1b172e9a4389123f2ce0f97cb2e92fcb..a0065f09bd50c855c51d33d75f5f6063e2dca554 100644 (file)
@@ -27,6 +27,7 @@ controllable.cc
 enumwriter.cc
 dmalloc.cc
 error.cc
+fpu.cc
 id.cc
 mountpoint.cc
 path.cc
diff --git a/libs/pbd/fpu.cc b/libs/pbd/fpu.cc
new file mode 100644 (file)
index 0000000..ae69b62
--- /dev/null
@@ -0,0 +1,92 @@
+#define _XOPEN_SOURCE 600
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <pbd/fpu.h>
+#include <pbd/error.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+using namespace std;
+
+FPU::FPU ()
+{
+       unsigned long cpuflags = 0;
+
+       _flags = Flags (0);
+
+#ifndef ARCH_X86
+       return;
+#endif
+       
+#ifndef USE_X86_64_ASM
+       asm volatile (
+               "mov $1, %%eax\n"
+               "pushl %%ebx\n"
+               "cpuid\n"
+               "movl %%edx, %0\n"
+               "popl %%ebx\n"
+               : "=r" (cpuflags)
+               : 
+               : "%eax", "%ecx", "%edx", "memory"
+               );
+       
+#else
+       
+       asm volatile (
+               "pushq %%rbx\n"
+               "movq $1, %%rax\n"
+               "cpuid\n"
+               "movq %%rdx, %0\n"
+               "popq %%rbx\n"
+               : "=r" (cpuflags)
+               : 
+               : "%rax", "%rcx", "%rdx", "memory"
+               );
+
+#endif /* USE_X86_64_ASM */
+       
+       if (cpuflags & (1<<25)) {
+               _flags = Flags (_flags | (HasSSE|HasFlushToZero));
+       }
+
+       if (cpuflags & (1<<26)) {
+               _flags = Flags (_flags | HasSSE2);
+       }
+
+       if (cpuflags & (1 << 24)) {
+               
+               char* fxbuf = 0;
+               
+               if (posix_memalign ((void**)&fxbuf, 16, 512)) {
+                       error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg;
+               } else {
+                       
+                       asm volatile (
+                               "fxsave (%0)"
+                               :
+                               : "r" (fxbuf)
+                               : "memory"
+                               );
+                       
+                       uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]);
+                       
+                       /* if the mask is zero, set its default value (from intel specs) */
+                       
+                       if (mxcsr_mask == 0) {
+                               mxcsr_mask = 0xffbf;
+                       }
+                       
+                       if (mxcsr_mask & (1<<6)) {
+                               _flags = Flags (_flags | HasDenormalsAreZero);
+                       } 
+
+                       free (fxbuf);
+               }
+       }
+}                      
+
+FPU::~FPU ()
+{
+}
diff --git a/libs/pbd/pbd/fpu.h b/libs/pbd/pbd/fpu.h
new file mode 100644 (file)
index 0000000..617dcdf
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __pbd_fpu_h__
+#define __pbd_fpu_h__
+
+namespace PBD {
+
+
+class FPU {
+  private:
+       enum Flags {
+               HasFlushToZero = 0x1,
+               HasDenormalsAreZero = 0x2,
+               HasSSE = 0x4,
+               HasSSE2 = 0x8
+       };
+
+  public:
+       FPU ();
+       ~FPU ();
+
+       bool has_flush_to_zero () const { return _flags & HasFlushToZero; }
+       bool has_denormals_are_zero () const { return _flags & HasDenormalsAreZero; }
+       bool has_sse () const { return _flags & HasSSE; }
+       bool has_sse2 () const { return _flags & HasSSE2; }
+       
+  private:
+       Flags _flags;
+};
+
+}
+
+#endif /* __pbd_fpu_h__ */