Audacity  2.2.0
NumberScale.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 NumberScale.h
6 
7 Paul Licameli
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_NUMBER_SCALE__
12 #define __AUDACITY_NUMBER_SCALE__
13 
14 #include <algorithm>
15 #include <cmath>
16 #include <wx/defs.h>
17 #include <wx/debug.h>
18 
26 
28 };
29 
30 
32 {
33 public:
35  : mType(nstLinear), mValue0(0), mValue1(1)
36  {}
37 
38  NumberScale(NumberScaleType type, float value0, float value1)
39  : mType(type)
40  {
41  switch (mType) {
42  case nstLinear:
43  {
44  mValue0 = value0;
45  mValue1 = value1;
46  }
47  break;
48  case nstLogarithmic:
49  {
50  mValue0 = logf(value0);
51  mValue1 = logf(value1);
52  }
53  break;
54  case nstMel:
55  {
56  mValue0 = hzToMel(value0);
57  mValue1 = hzToMel(value1);
58  }
59  break;
60  case nstBark:
61  {
62  mValue0 = hzToBark(value0);
63  mValue1 = hzToBark(value1);
64  }
65  break;
66  case nstErb:
67  {
68  mValue0 = hzToErb(value0);
69  mValue1 = hzToErb(value1);
70  }
71  break;
72  case nstPeriod:
73  {
74  mValue0 = hzToPeriod(value0);
75  mValue1 = hzToPeriod(value1);
76  }
77  break;
78  default:
79  wxASSERT(false);
80  }
81  }
82 
84  {
85  NumberScale result(*this);
86  std::swap(result.mValue0, result.mValue1);
87  return result;
88  }
89 
90  bool operator == (const NumberScale& other) const
91  {
92  return mType == other.mType
93  && mValue0 == other.mValue0
94  && mValue1 == other.mValue1;
95  }
96 
97  bool operator != (const NumberScale &other) const
98  {
99  return !(*this == other);
100  }
101 
102  static inline float hzToMel(float hz)
103  {
104  return 1127 * log(1 + hz / 700);
105  }
106 
107  static inline float melToHz(float mel)
108  {
109  return 700 * (exp(mel / 1127) - 1);
110  }
111 
112  static inline float hzToBark(float hz)
113  {
114  // Traunmueller's formula
115  const float z1 = 26.81 * hz / (1960 + hz) - 0.53;
116  if (z1 < 2.0)
117  return z1 + 0.15 * (2.0 - z1);
118  else if (z1 > 20.1)
119  return z1 + 0.22 * (z1 - 20.1);
120  else
121  return z1;
122  }
123 
124  static inline float barkToHz(float z1)
125  {
126  if (z1 < 2.0)
127  z1 = 2.0 + (z1 - 2.0) / 0.85;
128  else if (z1 > 20.1)
129  z1 = 20.1 + (z1 - 20.1) / 1.22;
130  return 1960 * (z1 + 0.53) / (26.28 - z1);
131  }
132 
133  static inline float hzToErb(float hz)
134  {
135  return 11.17268 * log(1 + (46.06538 * hz) / (hz + 14678.49));
136  }
137 
138  static inline float erbToHz(float erb)
139  {
140  return 676170.4 / (47.06538 - exp(0.08950404 * erb)) - 14678.49;
141  }
142 
143  static inline float hzToPeriod(float hz)
144  {
145  return -1.0 / std::max (1.0f, hz);
146  }
147 
148  static inline float periodToHz(float u)
149  {
150  return -1.0 / u;
151  }
152 
153  // Random access
154  float PositionToValue(float pp) const
155  {
156  switch (mType) {
157  default:
158  wxASSERT(false);
159  case nstLinear:
160  return mValue0 + pp * (mValue1 - mValue0);
161  case nstLogarithmic:
162  return exp(mValue0 + pp * (mValue1 - mValue0));
163  case nstMel:
164  return melToHz(mValue0 + pp * (mValue1 - mValue0));
165  case nstBark:
166  return barkToHz(mValue0 + pp * (mValue1 - mValue0));
167  case nstErb:
168  return erbToHz(mValue0 + pp * (mValue1 - mValue0));
169  case nstPeriod:
170  return periodToHz(mValue0 + pp * (mValue1 - mValue0));
171  }
172  }
173 
174  // STL-idiom iteration
175 
176  class Iterator
177  {
178  public:
179  Iterator(NumberScaleType type, float step, float value)
180  : mType(type), mStep(step), mValue(value)
181  {
182  }
183 
184  float operator * () const
185  {
186  switch (mType) {
187  default:
188  wxASSERT(false);
189  case nstLinear:
190  case nstLogarithmic:
191  return mValue;
192  case nstMel:
193  return melToHz(mValue);
194  case nstBark:
195  return barkToHz(mValue);
196  case nstErb:
197  return erbToHz(mValue);
198  case nstPeriod:
199  return periodToHz(mValue);
200  }
201  }
202 
204  {
205  switch (mType) {
206  case nstLinear:
207  case nstMel:
208  case nstBark:
209  case nstErb:
210  case nstPeriod:
211  mValue += mStep;
212  break;
213  case nstLogarithmic:
214  mValue *= mStep;
215  break;
216  default:
217  wxASSERT(false);
218  }
219  return *this;
220  }
221 
222  private:
224  const float mStep;
225  float mValue;
226  };
227 
228  Iterator begin(float nPositions) const
229  {
230  switch (mType) {
231  default:
232  wxASSERT(false);
233  case nstLinear:
234  case nstMel:
235  case nstBark:
236  case nstErb:
237  case nstPeriod:
238  return Iterator
239  (mType,
240  nPositions == 1 ? 0 : (mValue1 - mValue0) / (nPositions - 1),
241  mValue0);
242  case nstLogarithmic:
243  return Iterator
244  (mType,
245  nPositions == 1 ? 1 : exp((mValue1 - mValue0) / (nPositions - 1)),
246  exp(mValue0));
247  }
248  }
249 
250  // Inverse
251  float ValueToPosition(float val) const
252  {
253  switch (mType) {
254  default:
255  wxASSERT(false);
256  case nstLinear:
257  return ((val - mValue0) / (mValue1 - mValue0));
258  case nstLogarithmic:
259  return ((log(val) - mValue0) / (mValue1 - mValue0));
260  case nstMel:
261  return ((hzToMel(val) - mValue0) / (mValue1 - mValue0));
262  case nstBark:
263  return ((hzToBark(val) - mValue0) / (mValue1 - mValue0));
264  case nstErb:
265  return ((hzToErb(val) - mValue0) / (mValue1 - mValue0));
266  case nstPeriod:
267  return ((hzToPeriod(val) - mValue0) / (mValue1 - mValue0));
268  }
269  }
270 
271 private:
273  float mValue0;
274  float mValue1;
275 };
276 
277 #endif
Definition: NumberScale.h:25
const float mStep
Definition: NumberScale.h:224
float ValueToPosition(float val) const
Definition: NumberScale.h:251
Iterator begin(float nPositions) const
Definition: NumberScale.h:228
Definition: NumberScale.h:20
float PositionToValue(float pp) const
Definition: NumberScale.h:154
float operator*() const
Definition: NumberScale.h:184
Iterator(NumberScaleType type, float step, float value)
Definition: NumberScale.h:179
const NumberScaleType mType
Definition: NumberScale.h:223
static float hzToBark(float hz)
Definition: NumberScale.h:112
static float hzToMel(float hz)
Definition: NumberScale.h:102
NumberScale Reversal() const
Definition: NumberScale.h:83
Definition: NumberScale.h:31
static float hzToErb(float hz)
Definition: NumberScale.h:133
static float erbToHz(float erb)
Definition: NumberScale.h:138
static float barkToHz(float z1)
Definition: NumberScale.h:124
float mValue1
Definition: NumberScale.h:274
static float periodToHz(float u)
Definition: NumberScale.h:148
NumberScaleType
Definition: NumberScale.h:19
NumberScaleType mType
Definition: NumberScale.h:272
Definition: NumberScale.h:176
static float hzToPeriod(float hz)
Definition: NumberScale.h:143
Definition: NumberScale.h:27
bool operator!=(const NumberScale &other) const
Definition: NumberScale.h:97
float mValue
Definition: NumberScale.h:225
float mValue0
Definition: NumberScale.h:273
static float melToHz(float mel)
Definition: NumberScale.h:107
bool operator==(const NumberScale &other) const
Definition: NumberScale.h:90
Definition: NumberScale.h:21
Definition: NumberScale.h:22
Iterator & operator++()
Definition: NumberScale.h:203
Definition: NumberScale.h:24
NumberScale(NumberScaleType type, float value0, float value1)
Definition: NumberScale.h:38
NumberScale()
Definition: NumberScale.h:34
Definition: NumberScale.h:23