Audio Processing Framework (APF) version 0.5.0
denormalprevention.h
Go to the documentation of this file.
1/******************************************************************************
2 Copyright (c) 2012-2016 Institut für Nachrichtentechnik, Universität Rostock
3 Copyright (c) 2006-2012 Quality & Usability Lab
4 Deutsche Telekom Laboratories, TU Berlin
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23*******************************************************************************/
24
25// https://AudioProcessingFramework.github.io/
26
29
30#ifndef APF_DENORMALPREVENTION_H
31#define APF_DENORMALPREVENTION_H
32
33#include <limits> // for std::numeric_limits()
34#include <cmath> // for std::abs()
35
36#ifdef __SSE__
37#include <xmmintrin.h> // for SSE intrinsics
38#endif
39#ifdef __SSE3__
40#include <pmmintrin.h> // for SSE3 intrinsics
41#endif
42
43namespace apf
44{
45
49namespace dp
50{
51
53template<typename T>
54struct none
55{
56 void prevent_denormals(T&) {}
57};
58
59template<typename> struct dc; // default case not implemented!
60
62template<>
63struct dc<float>
64{
65 static void prevent_denormals(float& val) { val += 1e-18f; }
66};
67
69template<>
70struct dc<double>
71{
72 static void prevent_denormals(double& val) { val += 1e-30; }
73};
74
75template<typename> struct ac; // default case not implemented!
76
78template<>
79struct ac<float>
80{
81 public:
82 ac() : _anti_denorm(1e-18f) {}
83
84 void prevent_denormals(float& val)
85 {
86 _anti_denorm = -_anti_denorm;
87 val += _anti_denorm;
88 }
89
90 private:
91 float _anti_denorm;
92};
93
95template<>
96struct ac<double>
97{
98 public:
99 ac() : _anti_denorm(1e-30) {}
100
101 void prevent_denormals(double& val)
102 {
103 _anti_denorm = -_anti_denorm;
104 val += _anti_denorm;
105 }
106
107 private:
108 double _anti_denorm;
109};
110
111template<typename> struct quantization; // default case not implemented!
112
114template<>
115struct quantization<float>
116{
117 static void prevent_denormals(float& val)
118 {
119 val += 1e-18f;
120 val -= 1e-18f;
121 }
122};
123
125template<>
126struct quantization<double>
127{
128 static void prevent_denormals(double& val)
129 {
130 val += 1e-30;
131 val -= 1e-30;
132 }
133};
134
136template<typename T>
138{
139 static void prevent_denormals(T& val)
140 {
141 if (std::abs(val) < std::numeric_limits<T>::min() && (val != 0)) val = 0;
142 }
143};
144
146template<typename T>
148{
149 static void prevent_denormals(T& val)
150 {
151 if ((val != 0) && std::abs(val) < std::numeric_limits<T>::min()) val = 0;
152 }
153};
154
156template<typename T>
158{
159 static void prevent_denormals(T& val)
160 {
161 if (std::abs(val) < std::numeric_limits<T>::min()) val = 0;
162 }
163};
164
165#if 0
166// add noise component; equally distributed spectrum
167// NOTE: noise appears to be kind of deterministic
168// - temporarily deactivated due to warnings
169
170template<typename> struct NoisePrevention;
171
172template<>
173struct NoisePrevention<float>
174{
175 public:
176 NoisePrevention() : _rand_state(1) {}
177
178 void prevent_denormals(float& val)
179 {
180 _rand_state = _rand_state * 1234567UL + 890123UL;
181 int mantissa = _rand_state & 0x807F0000; // Keep only most significant bits
182 int flt_rnd = mantissa | 0x1E000000; // Set exponent
183 val += *reinterpret_cast<const float*>(&flt_rnd);
184 }
185
186 private:
187 unsigned int _rand_state;
188};
189#endif
190
191#ifdef __SSE__
192// The compiler must be set to generate SSE instructions automatically!
193// In GCC, this is done with -mfpmath=sse (which is on by default on amd64)
194
197inline void ftz_on()
198{
199 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
200}
201
204inline void ftz_off()
205{
206 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_OFF);
207}
208
209#ifdef __SSE3__
221void daz_on()
222{
223 _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
224}
225
229{
230 _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF);
231}
232#endif
233#endif
234
235} // namespace dp
236
237} // namespace apf
238
239#endif
void ftz_off()
Unset Flush-To-Zero (FTZ).
void daz_off()
Unset Denormals-Are-Zero (DAZ).
void daz_on()
Set Denormals-Are-Zero (DAZ).
void ftz_on()
Set Flush-To-Zero (FTZ).
Audio Processing Framework.
Definition: iterator.h:61
Disable denormal prevention.
Detect denormals and set 0.
Detect denormals and set 0.
Detect denormals and set 0.