diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-05-31 21:44:18 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-05-31 21:44:18 +0000 |
commit | 2291d59bc813597c95f2f00b2e8ae697f1f284f9 (patch) | |
tree | 6699041315f4bfa0cb605156fde098c143ad646a /libs | |
parent | c967b91ddf1bcd03ef44d62022b95257cbd94f60 (diff) |
add new denormal handling capabilities (95% finished)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@1935 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/ardour.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 8 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 7 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 60 | ||||
-rw-r--r-- | libs/ardour/route.cc | 36 |
7 files changed, 119 insertions, 4 deletions
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index 09c6bd8856..dbc08fff7c 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -75,6 +75,8 @@ namespace ARDOUR { }; static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */ + + void setup_fpu (); } /* how do we make these be within the Ardour namespace? */ diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 07e395c396..8003dc4a4c 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -140,6 +140,11 @@ CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true) CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120) +/* denormal management */ + +CONFIG_VARIABLE (bool, denormal_protection, "denormal-protection", false) +CONFIG_VARIABLE (DenormalModel, denormal_model, "denormal-model", DenormalNone) + /* BWAV */ CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US") diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 9bdd2cbca5..8f3cae0db1 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -127,6 +127,10 @@ class Route : public IO void set_phase_invert (bool yn, void *src); bool phase_invert() const { return _phase_invert; } + + void set_denormal_protection (bool yn, void *src); + bool denormal_protection() const { return _denormal_protection; } + void set_edit_group (RouteGroup *, void *); void drop_edit_group (void *); @@ -258,6 +262,7 @@ class Route : public IO bool _soloed : 1; bool _solo_safe : 1; bool _phase_invert : 1; + bool _denormal_protection : 1; bool _recordable : 1; bool _active : 1; bool _mute_affects_pre_fader : 1; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 7655f486e9..182172dff6 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -272,6 +272,13 @@ namespace ARDOUR { ExternalMonitoring, }; + enum DenormalModel { + DenormalNone, + DenormalFTZ, + DenormalDAZ, + DenormalFTZDAZ + }; + enum RemoteModel { UserOrdered, MixerOrdered, @@ -368,6 +375,7 @@ std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf); std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf); std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf); std::istream& operator>>(std::istream& o, ARDOUR::SmpteFormat& sf); +std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf); static inline nframes_t session_frame_to_track_frame (nframes_t session_frame, double speed) diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 345fbe771d..5a4ee251b6 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -51,6 +51,7 @@ setup_enum_writer () Placement _Placement; MonitorModel _MonitorModel; RemoteModel _RemoteModel; + DenormalModel _DenormalModel; CrossfadeModel _CrossfadeModel; LayerModel _LayerModel; SoloModel _SoloModel; @@ -162,6 +163,12 @@ setup_enum_writer () REGISTER_ENUM (ExternalMonitoring); REGISTER (_MonitorModel); + REGISTER_ENUM (DenormalNone); + REGISTER_ENUM (DenormalFTZ); + REGISTER_ENUM (DenormalDAZ); + REGISTER_ENUM (DenormalFTZDAZ); + REGISTER (_DenormalModel); + REGISTER_ENUM (UserOrdered); REGISTER_ENUM (MixerOrdered); REGISTER_ENUM (EditorOrdered); diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 2d22f4eb11..eb5a2cc9f2 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -28,6 +28,10 @@ #include <fst.h> #endif +#ifdef __SSE__ +#include <xmmintrin.h> +#endif + #include <lrdf.h> #include <pbd/error.h> @@ -228,8 +232,9 @@ setup_hardware_optimization (bool try_optimization) : "%rax", "%rcx", "%rdx", "memory"); #endif /* USE_X86_64_ASM */ + use_sse &= (1 << 25); // bit 25 = SSE support - + if (use_sse) { info << "Using SSE optimized routines" << endmsg; @@ -274,6 +279,9 @@ setup_hardware_optimization (bool try_optimization) info << "No H/W specific optimizations in use" << endmsg; } + + setup_fpu (); + } int @@ -527,6 +535,55 @@ ARDOUR::LocaleGuard::~LocaleGuard () free ((char*)old); } +void +ARDOUR::setup_fpu () +{ +#ifdef USE_XMMINTRIN + int MXCSR; + + /* 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) { + return; + } + + MXCSR = _mm_getcsr(); + + switch (Config->get_denormal_model()) { + case DenormalNone: + MXCSR &= ~_MM_FLUSH_ZERO_ON; + break; + + case DenormalFTZ: + MXCSR |= _MM_FLUSH_ZERO_ON; + break; + + case DenormalDAZ: + MXCSR &= ~_MM_FLUSH_ZERO_ON; + if (has_daz) { + MXCSR |= 0x8000; + } + break; + + case DenormalFTZDAZ: + if (has_daz) { + MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000; + } else { + MXCSR |= _MM_FLUSH_ZERO_ON; + } + break; + } + + _mm_setcsr (MXCSR); + +#endif +} + ARDOUR::OverlapType ARDOUR::coverage (nframes_t sa, nframes_t ea, nframes_t sb, nframes_t eb) @@ -629,4 +686,5 @@ std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type<ShuttleBehaviour> (o, var); } std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type<ShuttleUnits> (o, var); } std::istream& operator>>(std::istream& o, SmpteFormat& var) { return int_to_type<SmpteFormat> (o, var); } +std::istream& operator>>(std::istream& o, DenormalModel& var) { return int_to_type<DenormalModel> (o, var); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 3f9fa2737f..11132984f0 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -48,7 +48,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; - uint32_t Route::order_key_cnt = 0; @@ -78,6 +77,7 @@ Route::init () _soloed = false; _solo_safe = false; _phase_invert = false; + _denormal_protection = false; order_keys[strdup (N_("signal"))] = order_key_cnt++; _active = true; _silent = false; @@ -341,6 +341,22 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs, } } + /* ----------------------------------------------------------------------------------------------------- + DENORMAL CONTROL + -------------------------------------------------------------------------------------------------- */ + + if (_denormal_protection || Config->get_denormal_protection()) { + + for (n = 0; n < nbufs; ++n) { + Sample *sp = bufs[n]; + + for (nframes_t nx = offset; nx < nframes + offset; ++nx) { + sp[nx] += 1.0e-27f; + } + } + } + + /* ---------------------------------------------------------------------------------------------------- PRE-FADER REDIRECTS -------------------------------------------------------------------------------------------------- */ @@ -724,8 +740,17 @@ Route::set_phase_invert (bool yn, void *src) { if (_phase_invert != yn) { _phase_invert = yn; + // phase_invert_changed (src); /* EMIT SIGNAL */ + } +} + +void +Route::set_denormal_protection (bool yn, void *src) +{ + if (_denormal_protection != yn) { + _denormal_protection = yn; + // denormal_protection_changed (src); /* EMIT SIGNAL */ } - // phase_invert_changed (src); /* EMIT SIGNAL */ } void @@ -1404,6 +1429,7 @@ Route::state(bool full_state) node->add_property("muted", _muted?"yes":"no"); node->add_property("soloed", _soloed?"yes":"no"); node->add_property("phase-invert", _phase_invert?"yes":"no"); + node->add_property("denormal-protection", _denormal_protection?"yes":"no"); node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no"); node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no"); node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no"); @@ -1571,7 +1597,11 @@ Route::_set_state (const XMLNode& node, bool call_base) } if ((prop = node.property (X_("phase-invert"))) != 0) { - set_phase_invert(prop->value()=="yes"?true:false, this); + set_phase_invert (prop->value()=="yes"?true:false, this); + } + + if ((prop = node.property (X_("denormal-protection"))) != 0) { + set_denormal_protection (prop->value()=="yes"?true:false, this); } if ((prop = node.property (X_("active"))) != 0) { |