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