summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-05-31 21:44:18 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-05-31 21:44:18 +0000
commit2291d59bc813597c95f2f00b2e8ae697f1f284f9 (patch)
tree6699041315f4bfa0cb605156fde098c143ad646a /libs
parentc967b91ddf1bcd03ef44d62022b95257cbd94f60 (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.h2
-rw-r--r--libs/ardour/ardour/configuration_vars.h5
-rw-r--r--libs/ardour/ardour/route.h5
-rw-r--r--libs/ardour/ardour/types.h8
-rw-r--r--libs/ardour/enums.cc7
-rw-r--r--libs/ardour/globals.cc60
-rw-r--r--libs/ardour/route.cc36
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) {