Guitarix
clipping.h
Go to the documentation of this file.
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 
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 
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 
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 
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 
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 
147 static inline double opamp1(double x) {
148  int table = 9;
149  const table1dc& clip = *cliptable[table];
150  double f = fabs(x);
151  f = (f/(3.0 + f) - clip.low) * clip.istep;
152  int i = static_cast<int>(f);
153  if (i < 0) {
154  f = clip.data[0];
155  } else if (i >= clip.size-1) {
156  f = clip.data[clip.size-1];
157  } else {
158  f -= i;
159  f = clip.data[i]*(1-f) + clip.data[i+1]*f;
160  }
161  return copysign(f, -x);
162 }
163 
164 static inline double opamp2(double x) {
165  int table = 8;
166  const table1dc& clip = *cliptable[table];
167  double f = fabs(x);
168  f = (f/(3.0 + f) - clip.low) * clip.istep;
169  int i = static_cast<int>(f);
170  if (i < 0) {
171  f = clip.data[0];
172  } else if (i >= clip.size-1) {
173  f = clip.data[clip.size-1];
174  } else {
175  f -= i;
176  f = clip.data[i]*(1-f) + clip.data[i+1]*f;
177  }
178  return copysign(f, -x);
179 }
180 
181 static inline double asymhardclip(double x) {
182  int table = 0;
183  if (x<0) table = 1;
184  const table1dc& clip = *cliptable[table];
185  double f = fabs(x);
186  f = (f ) * clip.istep;
187  int i = static_cast<int>(f);
188  if (i < 0) {
189  f = clip.data[0];
190  } else if (i >= clip.size-1) {
191  f = clip.data[clip.size-1];
192  } else {
193  f -= i;
194  f = clip.data[i]*(1-f) + clip.data[i+1]*f;
195  }
196  return copysign(f, -x);
197 }
198 
199 
200 static inline double asymhardclip2(double x) {
201  int table = 2;
202  if (x<0) table = 3;
203  const table1dc& clip = *cliptable[table];
204  double f = fabs(x);
205  f = (f - clip.low) * clip.istep;
206  int i = static_cast<int>(f);
207  if (i < 0) {
208  f = clip.data[0];
209  } else if (i >= clip.size-1) {
210  f = clip.data[clip.size-1];
211  } else {
212  f -= i;
213  f = clip.data[i]*(1-f) + clip.data[i+1]*f;
214  }
215  return copysign(f, x);
216 }
217 
218 static inline double symclip(double x) {
219  int table = 6;
220  const table1dc& clip = *cliptable[table];
221  double f = fabs(x);
222  f = (f/(3.0 + f) - clip.low) * clip.istep;
223  int i = static_cast<int>(f);
224  if (i < 0) {
225  f = clip.data[0];
226  } else if (i >= clip.size-1) {
227  f = clip.data[clip.size-1];
228  } else {
229  f -= i;
230  f = clip.data[i]*(1-f) + clip.data[i+1]*f;
231  }
232  return copysign(f, -x);
233 }
234 
235 };