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