merge denormal handling work from 2.0-ongoing

git-svn-id: svn://localhost/ardour2/trunk@1937 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-06-01 02:27:21 +00:00
parent 0f2f4d8efc
commit 38ed75ff97
17 changed files with 260 additions and 15 deletions

View file

@ -36,6 +36,7 @@ opts.AddOptions(
BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0), BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0), BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1), 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('LIBLO', 'Compile with support for liblo library', 1),
BoolOption('NLS', 'Set to turn on i18n support', 1), BoolOption('NLS', 'Set to turn on i18n support', 1),
PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'), PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
@ -625,8 +626,8 @@ elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_6
opt_flags.append ("-march=i686") opt_flags.append ("-march=i686")
if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse: if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
opt_flags.extend (["-msse", "-mfpmath=sse"]) opt_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
debug_flags.extend (["-msse", "-mfpmath=sse"]) debug_flags.extend (["-msse", "-mfpmath=sse", "-DUSE_XMMINTRIN"])
# end of processor-specific section # end of processor-specific section
# optimization section # optimization section

View file

@ -340,7 +340,15 @@
<menuitem action='LayerLaterHigher'/> <menuitem action='LayerLaterHigher'/>
<menuitem action='LayerMoveAddHigher'/> <menuitem action='LayerMoveAddHigher'/>
<menuitem action='LayerAddHigher'/> <menuitem action='LayerAddHigher'/>
</menu> </menu>
<menu name='Denormals' action='Denormals'>
<menuitem action='DenormalProtection'/>
<separator/>
<menuitem action='DenormalNone'/>
<menuitem action='DenormalFTZ'/>
<menuitem action='DenormalDAZ'/>
<menuitem action='DenormalFTZDAZ'/>
</menu>
<separator/> <separator/>
<menuitem action='SendMTC'/> <menuitem action='SendMTC'/>
<menuitem action='SendMMC'/> <menuitem action='SendMMC'/>
@ -357,10 +365,8 @@
<menuitem action='StopRecordingOnXrun'/> <menuitem action='StopRecordingOnXrun'/>
<menuitem action='StopTransportAtEndOfSession'/> <menuitem action='StopTransportAtEndOfSession'/>
<menuitem action='GainReduceFastTransport'/> <menuitem action='GainReduceFastTransport'/>
<separator/> <menuitem action='PrimaryClockDeltaEditCursor'/>
<menuitem action='PrimaryClockDeltaEditCursor'/> <menuitem action='SecondaryClockDeltaEditCursor'/>
<menuitem action='SecondaryClockDeltaEditCursor'/>
<separator/>
</menu> </menu>
<menu name='Help' action='Help'> <menu name='Help' action='Help'>
<menuitem action='About'/> <menuitem action='About'/>

View file

@ -669,11 +669,14 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void toggle_use_osc (); void toggle_use_osc ();
void toggle_denormal_protection ();
void set_input_auto_connect (ARDOUR::AutoConnectOption); void set_input_auto_connect (ARDOUR::AutoConnectOption);
void set_output_auto_connect (ARDOUR::AutoConnectOption); void set_output_auto_connect (ARDOUR::AutoConnectOption);
void set_solo_model (ARDOUR::SoloModel); void set_solo_model (ARDOUR::SoloModel);
void set_monitor_model (ARDOUR::MonitorModel); void set_monitor_model (ARDOUR::MonitorModel);
void set_remote_model (ARDOUR::RemoteModel); void set_remote_model (ARDOUR::RemoteModel);
void set_denormal_model (ARDOUR::DenormalModel);
void toggle_StopPluginsWithTransport(); void toggle_StopPluginsWithTransport();
void toggle_DoNotRunPluginsWhileRecording(); void toggle_DoNotRunPluginsWhileRecording();
@ -692,6 +695,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void mtc_port_changed (); void mtc_port_changed ();
void map_solo_model (); void map_solo_model ();
void map_monitor_model (); void map_monitor_model ();
void map_denormal_model ();
void map_remote_model (); void map_remote_model ();
void map_file_header_format (); void map_file_header_format ();
void map_file_data_format (); void map_file_data_format ();

View file

@ -94,6 +94,7 @@ ARDOUR_UI::install_actions ()
ActionManager::register_action (main_actions, X_("Metering"), _("Metering")); ActionManager::register_action (main_actions, X_("Metering"), _("Metering"));
ActionManager::register_action (main_actions, X_("MeteringFallOffRate"), _("Fall off rate")); ActionManager::register_action (main_actions, X_("MeteringFallOffRate"), _("Fall off rate"));
ActionManager::register_action (main_actions, X_("MeteringHoldTime"), _("Hold Time")); ActionManager::register_action (main_actions, X_("MeteringHoldTime"), _("Hold Time"));
ActionManager::register_action (main_actions, X_("Denormals"), _("Denormal Handling"));
/* the real actions */ /* the real actions */
@ -416,6 +417,15 @@ ARDOUR_UI::install_actions ()
ActionManager::register_toggle_action (option_actions, X_("PrimaryClockDeltaEditCursor"), _("Primary Clock delta to edit cursor"), mem_fun (*this, &ARDOUR_UI::toggle_PrimaryClockDeltaEditCursor)); ActionManager::register_toggle_action (option_actions, X_("PrimaryClockDeltaEditCursor"), _("Primary Clock delta to edit cursor"), mem_fun (*this, &ARDOUR_UI::toggle_PrimaryClockDeltaEditCursor));
ActionManager::register_toggle_action (option_actions, X_("SecondaryClockDeltaEditCursor"), _("Secondary Clock delta to edit cursor"), mem_fun (*this, &ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor)); ActionManager::register_toggle_action (option_actions, X_("SecondaryClockDeltaEditCursor"), _("Secondary Clock delta to edit cursor"), mem_fun (*this, &ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor));
RadioAction::Group denormal_group;
ActionManager::register_toggle_action (option_actions, X_("DenormalProtection"), _("Use DC bias"), mem_fun (*this, &ARDOUR_UI::toggle_denormal_protection));
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_toggle_action (option_actions, X_("DoNotRunPluginsWhileRecording"), _("Do not run plugins while recording"), mem_fun (*this, &ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording)); 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); ActionManager::session_sensitive_actions.push_back (act);

View file

@ -75,6 +75,12 @@ ARDOUR_UI::toggle_send_midi_feedback ()
ActionManager::toggle_config_state ("options", "SendMIDIfeedback", &Configuration::set_midi_feedback, &Configuration::get_midi_feedback); ActionManager::toggle_config_state ("options", "SendMIDIfeedback", &Configuration::set_midi_feedback, &Configuration::get_midi_feedback);
} }
void
ARDOUR_UI::toggle_denormal_protection ()
{
ActionManager::toggle_config_state ("options", "DenormalProtection", &Configuration::set_denormal_protection, &Configuration::get_denormal_protection);
}
void void
ARDOUR_UI::set_native_file_header_format (HeaderFormat hf) ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
{ {
@ -292,6 +298,45 @@ ARDOUR_UI::set_monitor_model (MonitorModel model)
} }
void
ARDOUR_UI::set_denormal_model (DenormalModel model)
{
const char* action = 0;
switch (model) {
case DenormalNone:
action = X_("DenormalNone");
break;
case DenormalFTZ:
action = X_("DenormalFTZ");
break;
case DenormalDAZ:
action = X_("DenormalDAZ");
break;
case DenormalFTZDAZ:
action = X_("DenormalFTZDAZ");
break;
default:
fatal << string_compose (_("programming error: unknown denormal model in ARDOUR_UI::set_denormal_model: %1"), model) << endmsg;
/*NOTREACHED*/
}
Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
if (act) {
Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
if (ract && ract->get_active() && Config->get_denormal_model() != model) {
Config->set_denormal_model (model);
}
}
}
void void
ARDOUR_UI::toggle_auto_input () ARDOUR_UI::toggle_auto_input ()
{ {
@ -528,6 +573,36 @@ ARDOUR_UI::map_monitor_model ()
} }
} }
void
ARDOUR_UI::map_denormal_model ()
{
const char* on = 0;
switch (Config->get_denormal_model()) {
case DenormalNone:
on = X_("DenormalNone");
break;
case DenormalFTZ:
on = X_("DenormalFTZ");
break;
case DenormalDAZ:
on = X_("DenormalDAZ");
break;
case DenormalFTZDAZ:
on = X_("DenormalFTZDAZ");
break;
}
Glib::RefPtr<Action> act = ActionManager::get_action ("options", on);
if (act) {
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
if (tact && !tact->get_active()) {
tact->set_active (true);
}
}
}
void void
ARDOUR_UI::map_remote_model () ARDOUR_UI::map_remote_model ()
{ {
@ -917,6 +992,8 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
ActionManager::map_some_state ("options", "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end); ActionManager::map_some_state ("options", "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end);
} else if (PARAM_IS ("monitoring-model")) { } else if (PARAM_IS ("monitoring-model")) {
map_monitor_model (); map_monitor_model ();
} else if (PARAM_IS ("denormal-model")) {
map_denormal_model ();
} else if (PARAM_IS ("remote-model")) { } else if (PARAM_IS ("remote-model")) {
map_remote_model (); map_remote_model ();
} else if (PARAM_IS ("use-video-sync")) { } else if (PARAM_IS ("use-video-sync")) {

View file

@ -984,6 +984,9 @@ MixerStrip::build_route_ops_menu ()
items.push_back (CheckMenuElem (_("Invert Polarity"), mem_fun (*this, &RouteUI::toggle_polarity))); items.push_back (CheckMenuElem (_("Invert Polarity"), mem_fun (*this, &RouteUI::toggle_polarity)));
polarity_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); polarity_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
polarity_menu_item->set_active (_route->phase_invert()); polarity_menu_item->set_active (_route->phase_invert());
items.push_back (CheckMenuElem (_("Protect against denormals"), mem_fun (*this, &RouteUI::toggle_denormal_protection)));
denormal_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
build_remote_control_menu (); build_remote_control_menu ();

View file

@ -65,6 +65,8 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
wait_for_release = false; wait_for_release = false;
route_active_menu_item = 0; route_active_menu_item = 0;
was_solo_safe = false; was_solo_safe = false;
polarity_menu_item = 0;
denormal_menu_item = 0;
if (set_color_from_route()) { if (set_color_from_route()) {
set_color (unique_random_color()); set_color (unique_random_color());
@ -878,6 +880,28 @@ RouteUI::polarity_changed ()
/* no signal for this yet */ /* no signal for this yet */
} }
void
RouteUI::toggle_denormal_protection ()
{
if (denormal_menu_item) {
bool x;
ENSURE_GUI_THREAD(mem_fun (*this, &RouteUI::toggle_denormal_protection));
if ((x = denormal_menu_item->get_active()) != _route->denormal_protection()) {
_route->set_denormal_protection (x, this);
}
}
}
void
RouteUI::denormal_protection_changed ()
{
/* no signal for this yet */
}
void void
RouteUI::solo_safe_toggle(void* src, Gtk::CheckMenuItem* check) RouteUI::solo_safe_toggle(void* src, Gtk::CheckMenuItem* check)
{ {

View file

@ -145,6 +145,10 @@ class RouteUI : public virtual AxisView
void toggle_polarity (); void toggle_polarity ();
virtual void polarity_changed (); virtual void polarity_changed ();
Gtk::CheckMenuItem *denormal_menu_item;
void toggle_denormal_protection();
virtual void denormal_protection_changed ();
void disconnect_input (); void disconnect_input ();
void disconnect_output (); void disconnect_output ();

View file

@ -77,6 +77,8 @@ namespace ARDOUR {
}; };
static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */ 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? */ /* how do we make these be within the Ardour namespace? */

View file

@ -144,8 +144,14 @@ CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-bac
CONFIG_VARIABLE (string, possible_audio_file_regexp, "possible-audio-file-regexp", "\\.(wav|aiff|caf|w64|L|R)$") CONFIG_VARIABLE (string, possible_audio_file_regexp, "possible-audio-file-regexp", "\\.(wav|aiff|caf|w64|L|R)$")
/* Theme */ /* Theme */
CONFIG_VARIABLE (string, ui_rc_file, "ui-rc-file", "ardour2_ui_dark.rc") CONFIG_VARIABLE (string, ui_rc_file, "ui-rc-file", "ardour2_ui_dark.rc")
/* denormal management */
CONFIG_VARIABLE (bool, denormal_protection, "denormal-protection", false)
CONFIG_VARIABLE (DenormalModel, denormal_model, "denormal-model", DenormalNone)
/* BWAV */ /* BWAV */
CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US") CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US")

View file

@ -107,6 +107,9 @@ class IO : public PBD::StatefulDestructible
gain_t gain () const { return _desired_gain; } gain_t gain () const { return _desired_gain; }
virtual gain_t effective_gain () const; virtual gain_t effective_gain () const;
void set_denormal_protection (bool yn, void *src);
bool denormal_protection() const { return _denormal_protection; }
void set_phase_invert (bool yn, void *src); void set_phase_invert (bool yn, void *src);
bool phase_invert() const { return _phase_invert; } bool phase_invert() const { return _phase_invert; }
@ -284,6 +287,7 @@ class IO : public PBD::StatefulDestructible
Bundle* _output_bundle; Bundle* _output_bundle;
bool no_panner_reset; bool no_panner_reset;
bool _phase_invert; bool _phase_invert;
bool _denormal_protection;
XMLNode* deferred_state; XMLNode* deferred_state;
DataType _default_type; DataType _default_type;

View file

@ -124,7 +124,7 @@ class Route : public IO
void set_mute_config (mute_type, bool, void *src); void set_mute_config (mute_type, bool, void *src);
bool get_mute_config (mute_type); bool get_mute_config (mute_type);
void set_edit_group (RouteGroup *, void *); void set_edit_group (RouteGroup *, void *);
void drop_edit_group (void *); void drop_edit_group (void *);
RouteGroup *edit_group () { return _edit_group; } RouteGroup *edit_group () { return _edit_group; }

View file

@ -270,6 +270,13 @@ namespace ARDOUR {
ExternalMonitoring, ExternalMonitoring,
}; };
enum DenormalModel {
DenormalNone,
DenormalFTZ,
DenormalDAZ,
DenormalFTZDAZ
};
enum RemoteModel { enum RemoteModel {
UserOrdered, UserOrdered,
MixerOrdered, MixerOrdered,
@ -365,6 +372,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::ShuttleBehaviour& sf);
std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& 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::SmpteFormat& sf);
std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf);
using ARDOUR::nframes_t; using ARDOUR::nframes_t;

View file

@ -51,6 +51,7 @@ setup_enum_writer ()
Placement _Placement; Placement _Placement;
MonitorModel _MonitorModel; MonitorModel _MonitorModel;
RemoteModel _RemoteModel; RemoteModel _RemoteModel;
DenormalModel _DenormalModel;
CrossfadeModel _CrossfadeModel; CrossfadeModel _CrossfadeModel;
LayerModel _LayerModel; LayerModel _LayerModel;
SoloModel _SoloModel; SoloModel _SoloModel;
@ -162,6 +163,12 @@ setup_enum_writer ()
REGISTER_ENUM (ExternalMonitoring); REGISTER_ENUM (ExternalMonitoring);
REGISTER (_MonitorModel); REGISTER (_MonitorModel);
REGISTER_ENUM (DenormalNone);
REGISTER_ENUM (DenormalFTZ);
REGISTER_ENUM (DenormalDAZ);
REGISTER_ENUM (DenormalFTZDAZ);
REGISTER (_DenormalModel);
REGISTER_ENUM (UserOrdered); REGISTER_ENUM (UserOrdered);
REGISTER_ENUM (MixerOrdered); REGISTER_ENUM (MixerOrdered);
REGISTER_ENUM (EditorOrdered); REGISTER_ENUM (EditorOrdered);

View file

@ -27,6 +27,10 @@
#include <fst.h> #include <fst.h>
#endif #endif
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#include <lrdf.h> #include <lrdf.h>
#include <pbd/error.h> #include <pbd/error.h>
@ -237,8 +241,9 @@ setup_hardware_optimization (bool try_optimization)
: "%rax", "%rcx", "%rdx", "memory"); : "%rax", "%rcx", "%rdx", "memory");
#endif /* USE_X86_64_ASM */ #endif /* USE_X86_64_ASM */
use_sse &= (1 << 25); // bit 25 = SSE support use_sse &= (1 << 25); // bit 25 = SSE support
if (use_sse) { if (use_sse) {
info << "Using SSE optimized routines" << endmsg; info << "Using SSE optimized routines" << endmsg;
@ -283,6 +288,9 @@ setup_hardware_optimization (bool try_optimization)
info << "No H/W specific optimizations in use" << endmsg; info << "No H/W specific optimizations in use" << endmsg;
} }
setup_fpu ();
} }
int int
@ -532,6 +540,55 @@ ARDOUR::LocaleGuard::~LocaleGuard ()
free ((char*)old); 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::OverlapType
ARDOUR::coverage (nframes_t sa, nframes_t ea, ARDOUR::coverage (nframes_t sa, nframes_t ea,
nframes_t sb, nframes_t eb) nframes_t sb, nframes_t eb)
@ -634,4 +691,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, 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, 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, SmpteFormat& var) { return int_to_type<SmpteFormat> (o, var); }
std::istream& operator>>(std::istream& o, DenormalModel& var) { return int_to_type<DenormalModel> (o, var); }

View file

@ -2436,7 +2436,17 @@ IO::set_phase_invert (bool yn, void *src)
{ {
if (_phase_invert != yn) { if (_phase_invert != yn) {
_phase_invert = yn; _phase_invert = yn;
// phase_invert_changed (src); /* EMIT SIGNAL */
} }
// phase_invert_changed (src); /* EMIT SIGNAL */
} }
void
IO::set_denormal_protection (bool yn, void *src)
{
if (_denormal_protection != yn) {
_denormal_protection = yn;
// denormal_protection_changed (src); /* EMIT SIGNAL */
}
}

View file

@ -79,6 +79,7 @@ Route::init ()
_soloed = false; _soloed = false;
_solo_safe = false; _solo_safe = false;
_phase_invert = false; _phase_invert = false;
_denormal_protection = false;
order_keys[strdup (N_("signal"))] = order_key_cnt++; order_keys[strdup (N_("signal"))] = order_key_cnt++;
_active = true; _active = true;
_silent = false; _silent = false;
@ -234,9 +235,9 @@ Route::set_gain (gain_t val, void *src)
*/ */
void void
Route::process_output_buffers (BufferSet& bufs, Route::process_output_buffers (BufferSet& bufs,
nframes_t start_frame, nframes_t end_frame, nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset, bool with_redirects, int declick, nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
bool meter) bool meter)
{ {
// This is definitely very audio-only for now // This is definitely very audio-only for now
assert(_default_type == DataType::AUDIO); assert(_default_type == DataType::AUDIO);
@ -351,7 +352,22 @@ Route::process_output_buffers (BufferSet& bufs,
} }
} }
/* --------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------
DENORMAL CONTROL
-------------------------------------------------------------------------------------------------- */
if (_denormal_protection || Config->get_denormal_protection()) {
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
Sample* const sp = i->data();
for (nframes_t nx = offset; nx < nframes + offset; ++nx) {
sp[nx] += 1.0e-27f;
}
}
}
/* ----------------------------------------------------------------------------------------------------
PRE-FADER REDIRECTS PRE-FADER REDIRECTS
-------------------------------------------------------------------------------------------------- */ -------------------------------------------------------------------------------------------------- */
@ -1466,6 +1482,7 @@ Route::state(bool full_state)
node->add_property("muted", _muted?"yes":"no"); node->add_property("muted", _muted?"yes":"no");
node->add_property("soloed", _soloed?"yes":"no"); node->add_property("soloed", _soloed?"yes":"no");
node->add_property("phase-invert", _phase_invert?"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-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-post-fader", _mute_affects_post_fader?"yes":"no");
node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no"); node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no");
@ -1701,7 +1718,11 @@ Route::_set_state (const XMLNode& node, bool call_base)
} }
if ((prop = node.property (X_("phase-invert"))) != 0) { 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) { if ((prop = node.property (X_("active"))) != 0) {