1 /*
2 * Copyright (C) 2012 Andreas Degert, Hermann Meyer
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 namespace
19 {
20
21 struct table1dc { // 1-dimensional function table
22 float low;
23 float high;
24 float istep;
25 int size;
26 float data[];
27 };
28
29 template <int tab_size>
30 struct table1dc_imp {
31 float low;
32 float high;
33 float istep;
34 int size;
35 float data[tab_size];
36 operator table1dc&() const { return *(table1dc*)this; }
37 };
38
39 #include "clipt.cc"
40 #include "clipt1.cc"
41 #include "clipt2.cc"
42 #include "clipt3.cc"
43 #include "clipt4.cc"
44
45 table1dc *cliptable[10] = {
46 &static_cast<table1dc&>(clippingtable[0]),
47 &static_cast<table1dc&>(clippingtable[1]),
48 &static_cast<table1dc&>(clippingtable2[0]),
49 &static_cast<table1dc&>(clippingtable2[1]),
50 &static_cast<table1dc&>(clippingtable3[0]),
51 &static_cast<table1dc&>(clippingtable3[1]),
52 &static_cast<table1dc&>(clippingtable1[0]),
53 &static_cast<table1dc&>(clippingtable1[1]),
54 &static_cast<table1dc&>(clippingtable4[0]),
55 &static_cast<table1dc&>(clippingtable4[1]),
56 };
57
asymclip(double x)58 static inline double asymclip(double x) {
59 int table = 0;
60 if (x<0) table = 1;
61 const table1dc& clip = *cliptable[table];
62 double f = fabs(x);
63 f = (f/(3.0 + f) - clip.low) * clip.istep;
64 int i = static_cast<int>(f);
65 if (i < 0) {
66 f = clip.data[0];
67 } else if (i >= clip.size-1) {
68 f = clip.data[clip.size-1];
69 } else {
70 f -= i;
71 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
72 }
73 return copysign(f, -x);
74 }
75
asymclip2(double x)76 static inline double asymclip2(double x) {
77 int table = 2;
78 if (x<0) table = 3;
79 const table1dc& clip = *cliptable[table];
80 double f = fabs(x);
81 f = (f/(3.0 + f) - clip.low) * clip.istep;
82 int i = static_cast<int>(f);
83 if (i < 0) {
84 f = clip.data[0];
85 } else if (i >= clip.size-1) {
86 f = clip.data[clip.size-1];
87 } else {
88 f -= i;
89 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
90 }
91 return copysign(f, -x);
92 }
93
asymclip3(double x)94 static inline double asymclip3(double x) {
95 int table = 6;
96 if (x<0) table = 7;
97 const table1dc& clip = *cliptable[table];
98 double f = fabs(x);
99 f = (f/(3.0 + f) - clip.low) * clip.istep;
100 int i = static_cast<int>(f);
101 if (i < 0) {
102 f = clip.data[0];
103 } else if (i >= clip.size-1) {
104 f = clip.data[clip.size-1];
105 } else {
106 f -= i;
107 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
108 }
109 return copysign(f, -x);
110 }
111
asymclip4(double x)112 static inline double asymclip4(double x) {
113 int table = 6;
114 if (x<0) table = 1;
115 const table1dc& clip = *cliptable[table];
116 double f = fabs(x);
117 f = (f/(3.0 + f) - clip.low) * clip.istep;
118 int i = static_cast<int>(f);
119 if (i < 0) {
120 f = clip.data[0];
121 } else if (i >= clip.size-1) {
122 f = clip.data[clip.size-1];
123 } else {
124 f -= i;
125 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
126 }
127 return copysign(f, -x);
128 }
129
opamp(double x)130 static inline double opamp(double x) {
131 int table = 4;
132 const table1dc& clip = *cliptable[table];
133 double f = fabs(x);
134 f = (f/(3.0 + f) - clip.low) * clip.istep;
135 int i = static_cast<int>(f);
136 if (i < 0) {
137 f = clip.data[0];
138 } else if (i >= clip.size-1) {
139 f = clip.data[clip.size-1];
140 } else {
141 f -= i;
142 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
143 }
144 return copysign(f, -x);
145 }
146
opamp1(double x)147 static inline double opamp1(double x) {
148 int table = 9;
149 if (x<0) table = 8;
150 const table1dc& clip = *cliptable[table];
151 double f = fabs(x);
152 f = (f/(3.0 + f) - clip.low) * clip.istep;
153 int i = static_cast<int>(f);
154 if (i < 0) {
155 f = clip.data[0];
156 } else if (i >= clip.size-1) {
157 f = clip.data[clip.size-1];
158 } else {
159 f -= i;
160 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
161 }
162 return copysign(f, -x);
163 }
164
opamp2(double x)165 static inline double opamp2(double x) {
166 int table = 8;
167 const table1dc& clip = *cliptable[table];
168 double f = fabs(x);
169 f = (f/(3.0 + f) - clip.low) * clip.istep;
170 int i = static_cast<int>(f);
171 if (i < 0) {
172 f = clip.data[0];
173 } else if (i >= clip.size-1) {
174 f = clip.data[clip.size-1];
175 } else {
176 f -= i;
177 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
178 }
179 return copysign(f, -x);
180 }
181
asymhardclip(double x)182 static inline double asymhardclip(double x) {
183 int table = 0;
184 if (x<0) table = 1;
185 const table1dc& clip = *cliptable[table];
186 double f = fabs(x);
187 f = (f ) * clip.istep;
188 int i = static_cast<int>(f);
189 if (i < 0) {
190 f = clip.data[0];
191 } else if (i >= clip.size-1) {
192 f = clip.data[clip.size-1];
193 } else {
194 f -= i;
195 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
196 }
197 return copysign(f, -x);
198 }
199
200
asymhardclip2(double x)201 static inline double asymhardclip2(double x) {
202 int table = 2;
203 if (x<0) table = 3;
204 const table1dc& clip = *cliptable[table];
205 double f = fabs(x);
206 f = (f - clip.low) * clip.istep;
207 int i = static_cast<int>(f);
208 if (i < 0) {
209 f = clip.data[0];
210 } else if (i >= clip.size-1) {
211 f = clip.data[clip.size-1];
212 } else {
213 f -= i;
214 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
215 }
216 return copysign(f, x);
217 }
218
symclip(double x)219 static inline double symclip(double x) {
220 int table = 6;
221 const table1dc& clip = *cliptable[table];
222 double f = fabs(x);
223 f = (f/(3.0 + f) - clip.low) * clip.istep;
224 int i = static_cast<int>(f);
225 if (i < 0) {
226 f = clip.data[0];
227 } else if (i >= clip.size-1) {
228 f = clip.data[clip.size-1];
229 } else {
230 f -= i;
231 f = clip.data[i]*(1-f) + clip.data[i+1]*f;
232 }
233 return copysign(f, -x);
234 }
235
236 };
237